initial commit
This commit is contained in:
		
							
								
								
									
										20
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
dist
 | 
			
		||||
dist-*
 | 
			
		||||
cabal-dev
 | 
			
		||||
*.o
 | 
			
		||||
*.hi
 | 
			
		||||
*.chi
 | 
			
		||||
*.chs.h
 | 
			
		||||
*.dyn_o
 | 
			
		||||
*.dyn_hi
 | 
			
		||||
.hpc
 | 
			
		||||
.hsenv
 | 
			
		||||
.cabal-sandbox/
 | 
			
		||||
cabal.sandbox.config
 | 
			
		||||
*.prof
 | 
			
		||||
*.aux
 | 
			
		||||
*.hp
 | 
			
		||||
*.eventlog
 | 
			
		||||
.stack-work/
 | 
			
		||||
cabal.project.local
 | 
			
		||||
*~
 | 
			
		||||
							
								
								
									
										41
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
# This is the simple Travis configuration, which is intended for use
 | 
			
		||||
# on applications which do not require cross-platform and
 | 
			
		||||
# multiple-GHC-version support. For more information and other
 | 
			
		||||
# options, see:
 | 
			
		||||
#
 | 
			
		||||
# https://docs.haskellstack.org/en/stable/travis_ci/
 | 
			
		||||
#
 | 
			
		||||
# Copy these contents into the root directory of your Github project in a file
 | 
			
		||||
# named .travis.yml
 | 
			
		||||
 | 
			
		||||
# Use new container infrastructure to enable caching
 | 
			
		||||
sudo: false
 | 
			
		||||
 | 
			
		||||
# Do not choose a language; we provide our own build tools.
 | 
			
		||||
language: generic
 | 
			
		||||
 | 
			
		||||
# Caching so the next build will be fast too.
 | 
			
		||||
cache:
 | 
			
		||||
  directories:
 | 
			
		||||
  - $HOME/.stack
 | 
			
		||||
 | 
			
		||||
# Ensure necessary system libraries are present
 | 
			
		||||
addons:
 | 
			
		||||
  apt:
 | 
			
		||||
    packages:
 | 
			
		||||
      - libgmp-dev
 | 
			
		||||
 | 
			
		||||
before_install:
 | 
			
		||||
# Download and unpack the stack executable
 | 
			
		||||
- mkdir -p ~/.local/bin
 | 
			
		||||
- export PATH=$HOME/.local/bin:$PATH
 | 
			
		||||
- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
# Build dependencies
 | 
			
		||||
- stack --no-terminal --install-ghc test --only-dependencies
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
# Build the package, its tests, and its docs and run the tests
 | 
			
		||||
- stack --no-terminal test --haddock --no-haddock-deps
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										30
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
Copyright Author name here (c) 2017
 | 
			
		||||
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
    * Redistributions of source code must retain the above copyright
 | 
			
		||||
      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
    * Redistributions in binary form must reproduce the above
 | 
			
		||||
      copyright notice, this list of conditions and the following
 | 
			
		||||
      disclaimer in the documentation and/or other materials provided
 | 
			
		||||
      with the distribution.
 | 
			
		||||
 | 
			
		||||
    * Neither the name of Author name here nor the names of other
 | 
			
		||||
      contributors may be used to endorse or promote products derived
 | 
			
		||||
      from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
							
								
								
									
										111
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
Übungszettel 1
 | 
			
		||||
==============
 | 
			
		||||
 | 
			
		||||
Dieses Repository dient der ersten Übung des Moduls Fortgeschrittene
 | 
			
		||||
Funktionale Programmierung in Haskell. 
 | 
			
		||||
Wir werden sowohl in den Übungen als auch für das Projekt als Compiler den GHC
 | 
			
		||||
in Version >= 8 verwenden, sowie stack, ein Progamm zur Unterstützung der
 | 
			
		||||
Entwicklung von Haskell programmen.
 | 
			
		||||
 | 
			
		||||
Als Editor/IDE empfehlen wir nvim.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Stack
 | 
			
		||||
-----
 | 
			
		||||
> $ stack update
 | 
			
		||||
 | 
			
		||||
Neuste Paketliste laden
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> $ stack setup
 | 
			
		||||
 | 
			
		||||
Läd den GHC und andere erforderliche Daten für ein das Projekt herunter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> $ stack build
 | 
			
		||||
 | 
			
		||||
Baut das Projekt
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> $ stack test
 | 
			
		||||
 | 
			
		||||
Testet das Projekt
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> $ stack haddock
 | 
			
		||||
 | 
			
		||||
Generiert die Dokumentation für das Projekt
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> $ stack ghci
 | 
			
		||||
 | 
			
		||||
Compiliert das Projekt und startet den GHCi im Kontext des Projekts
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> $ stack help
 | 
			
		||||
 | 
			
		||||
Try for yourself
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Github
 | 
			
		||||
------
 | 
			
		||||
 | 
			
		||||
Wir verwenden Github statt des Lernraums/LernraumPLUS/moodle/etc.
 | 
			
		||||
Das bedeutet, dass ihr einen Github-Account braucht.
 | 
			
		||||
 | 
			
		||||
Das hoch und runterladen der Aufgaben / des Projekts erfolgt mit dem
 | 
			
		||||
Kommandozeilenprogramm git.
 | 
			
		||||
 | 
			
		||||
> $ git clone https://github.com/[..]
 | 
			
		||||
 | 
			
		||||
Klont ein git-repository in eine extra dafür neu angelegten Ordner
 | 
			
		||||
 | 
			
		||||
> $ git status
 | 
			
		||||
 | 
			
		||||
Zeigt den status des git-repository's an. Das bedeutet, welche Dateien
 | 
			
		||||
verändert wurden, und welche Änderungen "staged for commit" sind, dh. in einen
 | 
			
		||||
Commit einfließen werden.
 | 
			
		||||
 | 
			
		||||
> $ git commit -am "Aufgabe1.hs solved"
 | 
			
		||||
 | 
			
		||||
Speichert alle Änderungen, die staged sind, in einen Commit mit einer Commit
 | 
			
		||||
Message.
 | 
			
		||||
 | 
			
		||||
> $ git push
 | 
			
		||||
 | 
			
		||||
Pusht die Commits, dh. läd alle Commits hoch.
 | 
			
		||||
 | 
			
		||||
Falls ihr nvim verwendet, gibt es im Editor einige Plugins für eine direkte
 | 
			
		||||
Integration von git.
 | 
			
		||||
 | 
			
		||||
Github Classroom
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
Ihr werdet einen Link an eure Github-Mail erhalten, welcher euch Zugang einem
 | 
			
		||||
Assignment gibt.
 | 
			
		||||
 | 
			
		||||
Jedes Assignment erstellt ein neues privaten Repository mit der
 | 
			
		||||
Aufgabenstellung, in welches ihr eure Lösungen hochladen könnt.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Travis CI
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
Travis ist ein continuous integration service. Immer wenn ihr eine Aufgabe
 | 
			
		||||
bearbeitet habt und diese auf Github pusht, läd Travis diesen push in eine
 | 
			
		||||
virtuelle Maschiene und baut und testet die neue Version.
 | 
			
		||||
 | 
			
		||||
Das bedeutet folgendes:
 | 
			
		||||
- Ihr bekommt direkt Feedback zu euren Lösungen
 | 
			
		||||
- Wir bekommen eine Mail wenn ein Build fehlschlägt/fehlerfrei durchläuft
 | 
			
		||||
- Ihr habt ein Konsolen-Log, in dem Ihr einezelne Zeilen makieren könnt und
 | 
			
		||||
  anschließend den Link an uns weiterleiten könnt um genaue Erklärungen
 | 
			
		||||
  bzw. Lösungshilfen zu Fehlern zu bekommen
 | 
			
		||||
 | 
			
		||||
Mit anderen Worten, ihr müsst nicht im Tutorium sitzen um effizient mit euren
 | 
			
		||||
Tutoren zu kommunizieren
 | 
			
		||||
							
								
								
									
										6
									
								
								app/Aufgabe1Main.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/Aufgabe1Main.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
module Main where
 | 
			
		||||
 | 
			
		||||
import Aufgabe1
 | 
			
		||||
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = putStrLn result
 | 
			
		||||
							
								
								
									
										6
									
								
								app/Aufgabe2Main.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/Aufgabe2Main.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
module Main where
 | 
			
		||||
 | 
			
		||||
import Aufgabe2
 | 
			
		||||
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = putStrLn result
 | 
			
		||||
							
								
								
									
										6
									
								
								app/Aufgabe3Main.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/Aufgabe3Main.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
module Main where
 | 
			
		||||
 | 
			
		||||
import Aufgabe3
 | 
			
		||||
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = putStrLn result
 | 
			
		||||
							
								
								
									
										6
									
								
								app/Aufgabe4Main.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								app/Aufgabe4Main.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
module Main where
 | 
			
		||||
 | 
			
		||||
import Aufgabe4
 | 
			
		||||
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = putStrLn result
 | 
			
		||||
							
								
								
									
										48
									
								
								src/Aufgabe1.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/Aufgabe1.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
{-
 | 
			
		||||
        Aufgabe 1
 | 
			
		||||
        =========
 | 
			
		||||
-}
 | 
			
		||||
module Aufgabe1 where
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{-      Gegeben ist der Datentyp Pred a, der eine Prüffunktion (Prädikat) repräsentiert, 
 | 
			
		||||
        die einen Wert vom Typ a zu einem Wert vom Typ Bool auswertet. 
 | 
			
		||||
        Beachten Sie, dass mit dem Wertekonstruktor Pred bereits eine Funktion 
 | 
			
		||||
        Pred :: (a -> Bool) -> Pred a 
 | 
			
		||||
        gegeben ist, mit der Sie ein Prädikat "einpacken" können.  
 | 
			
		||||
-}
 | 
			
		||||
 | 
			
		||||
newtype Pred a = Pred (a -> Bool)
 | 
			
		||||
 | 
			
		||||
{-      Schreiben Sie eine Funktion unPred, die das Prädikat "auspackt". 
 | 
			
		||||
-}
 | 
			
		||||
 | 
			
		||||
unPred :: Pred a -> (a -> Bool)
 | 
			
		||||
unPred = undefined
 | 
			
		||||
 | 
			
		||||
{-      Da Haskell-Funktionen grundsätzlich “gecurried” sind, bzw. der (->)-Operator  
 | 
			
		||||
        rechtsassoziativ ist, können Sie die Klammern hinten in der Signatur auch weglassen 
 | 
			
		||||
        und erhalten unPred :: Pred a -> a -> Bool, was man zugleich als “wende Pred a an, 
 | 
			
		||||
        wenn du ein a bekommst” lesen kann.
 | 
			
		||||
-}
 | 
			
		||||
 | 
			
		||||
{-      Definieren Sie nun eine Funktion isVowel, die prüft, ob ein Buchstabe ein Vokal ist.    
 | 
			
		||||
-}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
isVowel :: Pred Char
 | 
			
		||||
isVowel = undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{-
 | 
			
		||||
        Schreiben Sie eine Funktion filterVowels, die alle Vorkommen von Vokalen aus
 | 
			
		||||
        einem String entfernt. Verwenden Sie hierfür das Prädikat isVowel. 
 | 
			
		||||
-}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
filterVowels :: String -> String
 | 
			
		||||
filterVowels = undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
result :: String
 | 
			
		||||
result = filterVowels "Hello World!"
 | 
			
		||||
							
								
								
									
										47
									
								
								src/Aufgabe1.lhs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/Aufgabe1.lhs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
Aufgabe 1
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
> module Aufgabe1 where
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Gegeben ist der Datentyp Pred a, der eine Prüffunktion (Prädikat) repräsentiert, 
 | 
			
		||||
die einen Wert vom Typ a zu einem Wert vom Typ Bool auswertet. 
 | 
			
		||||
Beachten Sie, dass mit dem Wertekonstruktor Pred bereits eine Funktion 
 | 
			
		||||
Pred :: (a -> Bool) -> Pred a 
 | 
			
		||||
gegeben ist, mit der Sie ein Prädikat "einpacken" können.
 | 
			
		||||
 | 
			
		||||
> newtype Pred a = Pred (a -> Bool)
 | 
			
		||||
 | 
			
		||||
Schreiben Sie eine Funktion unPred, die das Prädikat "auspackt". 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> unPred :: Pred a -> (a -> Bool)
 | 
			
		||||
>
 | 
			
		||||
> unPred = undefined
 | 
			
		||||
 | 
			
		||||
Da Haskell-Funktionen grundsätzlich “gecurried” sind, bzw. der (->)-Operator
 | 
			
		||||
rechtsassoziativ ist, können Sie die Klammern hinten in der Signatur auch weglassen 
 | 
			
		||||
und erhalten unPred :: Pred a -> a -> Bool, was man zugleich als “wende Pred a an, 
 | 
			
		||||
wenn du ein a bekommst” lesen kann.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Definieren Sie nun eine Funktion isVowel, die prüft, ob ein Buchstabe ein Vokal ist.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> isVowel :: Pred Char
 | 
			
		||||
>
 | 
			
		||||
> isVowel = undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Schreiben Sie eine Funktion filterVowels, die alle Vorkommen von Vokalen aus
 | 
			
		||||
einem String entfernt. Verwenden Sie hierfür das Prädikat isVowel. 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> filterVowels :: String -> String
 | 
			
		||||
>
 | 
			
		||||
> filterVowels = undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> result :: String
 | 
			
		||||
>
 | 
			
		||||
> result = filterVowels "Hello World!"
 | 
			
		||||
							
								
								
									
										47
									
								
								src/Aufgabe1.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/Aufgabe1.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
Aufgabe 1
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
> module Aufgabe1 where
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Gegeben ist der Datentyp Pred a, der eine Prüffunktion (Prädikat) repräsentiert, 
 | 
			
		||||
die einen Wert vom Typ a zu einem Wert vom Typ Bool auswertet. 
 | 
			
		||||
Beachten Sie, dass mit dem Wertekonstruktor Pred bereits eine Funktion 
 | 
			
		||||
Pred :: (a -> Bool) -> Pred a 
 | 
			
		||||
gegeben ist, mit der Sie ein Prädikat "einpacken" können.
 | 
			
		||||
 | 
			
		||||
> newtype Pred a = Pred (a -> Bool)
 | 
			
		||||
 | 
			
		||||
Schreiben Sie eine Funktion unPred, die das Prädikat "auspackt". 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> unPred :: Pred a -> (a -> Bool)
 | 
			
		||||
>
 | 
			
		||||
> unPred = undefined
 | 
			
		||||
 | 
			
		||||
Da Haskell-Funktionen grundsätzlich “gecurried” sind, bzw. der (->)-Operator
 | 
			
		||||
rechtsassoziativ ist, können Sie die Klammern hinten in der Signatur auch weglassen 
 | 
			
		||||
und erhalten unPred :: Pred a -> a -> Bool, was man zugleich als “wende Pred a an, 
 | 
			
		||||
wenn du ein a bekommst” lesen kann.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Definieren Sie nun eine Funktion isVowel, die prüft, ob ein Buchstabe ein Vokal ist.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> isVowel :: Pred Char
 | 
			
		||||
>
 | 
			
		||||
> isVowel = undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Schreiben Sie eine Funktion filterVowels, die alle Vorkommen von Vokalen aus
 | 
			
		||||
einem String entfernt. Verwenden Sie hierfür das Prädikat isVowel. 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> filterVowels :: String -> String
 | 
			
		||||
>
 | 
			
		||||
> filterVowels = undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> result :: String
 | 
			
		||||
>
 | 
			
		||||
> result = filterVowels "Hello World!"
 | 
			
		||||
							
								
								
									
										41
									
								
								src/Aufgabe2.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/Aufgabe2.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
-- Aufgabe 2
 | 
			
		||||
-- =========
 | 
			
		||||
 | 
			
		||||
module Aufgabe2 where
 | 
			
		||||
 | 
			
		||||
-- Machen Sie sich mit den Modulen
 | 
			
		||||
 | 
			
		||||
import List
 | 
			
		||||
 | 
			
		||||
import ERPSys
 | 
			
		||||
 | 
			
		||||
-- vertraut. Einige der Aufgaben diese Woche basieren auf diesen.
 | 
			
		||||
 | 
			
		||||
-- Hypothetisches Real-World Problem
 | 
			
		||||
-- ---------------------------------
 | 
			
		||||
 | 
			
		||||
-- Gegeben ein bereits existierendes Warenwirtschaftssystem (Modul ERPSys), welches
 | 
			
		||||
-- auf einer eigenen Datenstruktur (Modul List) basiert.
 | 
			
		||||
 | 
			
		||||
-- Die Firma, in der Sie arbeiten wird beauftragt, ein neues Kassensystem zu
 | 
			
		||||
-- entwickeln. Sie werden beauftragt, den Scanalogorithmus der Kasse zu
 | 
			
		||||
-- programmieren.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- Dazu ist zuerst die Funktion `findArticle` zu entwickeln, die gegeben einen
 | 
			
		||||
-- Barcode und eine Produktliste einen Artikel findet.
 | 
			
		||||
 | 
			
		||||
findArticle :: (Eq a) => a -> ProductList a b c -> Maybe (Article a b c)
 | 
			
		||||
 | 
			
		||||
findArticle = undefined
 | 
			
		||||
 | 
			
		||||
productCatalog :: ProductList Int String Float
 | 
			
		||||
productCatalog = insert (Article 1 "Apfel" 1)
 | 
			
		||||
               $ insert (Article 2 "Birne" 0.5)
 | 
			
		||||
               $ insert (Article 3 "Banane" 1.5)
 | 
			
		||||
               $ insert (Article 4 "Tomate" 0.75)
 | 
			
		||||
                 ListEnd
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
result = show $ findArticle 2 productCatalog
 | 
			
		||||
							
								
								
									
										41
									
								
								src/Aufgabe2.lhs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/Aufgabe2.lhs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
Aufgabe 2
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
> module Aufgabe2 where
 | 
			
		||||
 | 
			
		||||
Machen Sie sich mit den Modulen
 | 
			
		||||
 | 
			
		||||
> import List
 | 
			
		||||
>
 | 
			
		||||
> import ERPSys
 | 
			
		||||
 | 
			
		||||
vertraut. Einige der Aufgaben diese Woche basieren auf diesen.
 | 
			
		||||
 | 
			
		||||
Hypothetisches Real-World Problem
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
Gegeben ein bereits existierendes Warenwirtschaftssystem (Modul `ERPSys`), welches
 | 
			
		||||
auf einer eigenen Datenstruktur (Modul `List`) basiert.
 | 
			
		||||
 | 
			
		||||
Die Firma, in der Sie arbeiten wird beauftragt, ein neues Kassensystem zu
 | 
			
		||||
entwickeln. Sie werden beauftragt, eine Teil des Scanalogorithmuses der Kasse zu
 | 
			
		||||
programmieren.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Dazu ist zuerst die Funktion `findArticle` zu entwickeln, die gegeben einen
 | 
			
		||||
Barcode und eine Produktliste einen Artikel findet.
 | 
			
		||||
 | 
			
		||||
> findArticle :: (Eq a) => a -> ProductList a b c -> Maybe (Article a b c)
 | 
			
		||||
>
 | 
			
		||||
> findArticle = undefined
 | 
			
		||||
 | 
			
		||||
> productCatalog :: ProductList Int String Float
 | 
			
		||||
> productCatalog = insert (Article 1 "Apfel" 1)
 | 
			
		||||
>                $ insert (Article 2 "Birne" 0.5)
 | 
			
		||||
>                $ insert (Article 3 "Banane" 1.5)
 | 
			
		||||
>                $ insert (Article 4 "Tomate" 0.75)
 | 
			
		||||
>                  ListEnd
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> result = show $ findArticle 2 productCatalog
 | 
			
		||||
							
								
								
									
										41
									
								
								src/Aufgabe2.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/Aufgabe2.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
Aufgabe 2
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
> module Aufgabe2 where
 | 
			
		||||
 | 
			
		||||
Machen Sie sich mit den Modulen
 | 
			
		||||
 | 
			
		||||
> import List
 | 
			
		||||
>
 | 
			
		||||
> import ERPSys
 | 
			
		||||
 | 
			
		||||
vertraut. Einige der Aufgaben diese Woche basieren auf diesen.
 | 
			
		||||
 | 
			
		||||
Hypothetisches Real-World Problem
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
Gegeben ein bereits existierendes Warenwirtschaftssystem (Modul `ERPSys`), welches
 | 
			
		||||
auf einer eigenen Datenstruktur (Modul `List`) basiert.
 | 
			
		||||
 | 
			
		||||
Die Firma, in der Sie arbeiten wird beauftragt, ein neues Kassensystem zu
 | 
			
		||||
entwickeln. Sie werden beauftragt, eine Teil des Scanalogorithmuses der Kasse zu
 | 
			
		||||
programmieren.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Dazu ist zuerst die Funktion `findArticle` zu entwickeln, die gegeben einen
 | 
			
		||||
Barcode und eine Produktliste einen Artikel findet.
 | 
			
		||||
 | 
			
		||||
> findArticle :: (Eq a) => a -> ProductList a b c -> Maybe (Article a b c)
 | 
			
		||||
>
 | 
			
		||||
> findArticle = undefined
 | 
			
		||||
 | 
			
		||||
> productCatalog :: ProductList Int String Float
 | 
			
		||||
> productCatalog = insert (Article 1 "Apfel" 1)
 | 
			
		||||
>                $ insert (Article 2 "Birne" 0.5)
 | 
			
		||||
>                $ insert (Article 3 "Banane" 1.5)
 | 
			
		||||
>                $ insert (Article 4 "Tomate" 0.75)
 | 
			
		||||
>                  ListEnd
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> result = show $ findArticle 2 productCatalog
 | 
			
		||||
							
								
								
									
										31
									
								
								src/Aufgabe3.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/Aufgabe3.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
-- Aufgabe 3
 | 
			
		||||
-- =========
 | 
			
		||||
 | 
			
		||||
module Aufgabe3 where
 | 
			
		||||
 | 
			
		||||
import Data.Maybe (fromMaybe)
 | 
			
		||||
 | 
			
		||||
import List
 | 
			
		||||
 | 
			
		||||
import ERPSys
 | 
			
		||||
 | 
			
		||||
import Aufgabe2
 | 
			
		||||
 | 
			
		||||
-- Die Funktion scan soll, aus einer `ProductList` (2. Argument) anhand eines
 | 
			
		||||
-- Barcodes (1. Argument) einen Artikel finden und diesen dann in eine 
 | 
			
		||||
-- Scannerliste einfügen. Wurde kein Artiekl gefunden gibt `scan` `Nothing` zurück.
 | 
			
		||||
-- Um die eigentliche Funktion `scan` zu implementieren, empfiehlt es sich, zuerst
 | 
			
		||||
-- eine Instanz `Eq` für `Article` zu definieren.
 | 
			
		||||
-- Diese sollte anhand des Barcodes die Gleichheit eines Artikels bestimmen.
 | 
			
		||||
 | 
			
		||||
scan :: (Eq a) => a -> ProductList a b c -> ScannerList a b c -> Maybe (ScannerList a b c)
 | 
			
		||||
 | 
			
		||||
scan = undefined
 | 
			
		||||
 | 
			
		||||
instance (Eq a) => Eq (Article a b c) where
 | 
			
		||||
 | 
			
		||||
  (==) = undefined
 | 
			
		||||
 | 
			
		||||
result = show $ scan 1 productCatalog
 | 
			
		||||
       $ fromMaybe AmountListEnd $ scan 2 productCatalog
 | 
			
		||||
       $ fromMaybe AmountListEnd $ scan 1 productCatalog AmountListEnd
 | 
			
		||||
							
								
								
									
										31
									
								
								src/Aufgabe3.lhs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/Aufgabe3.lhs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
Aufgabe 3
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
> module Aufgabe3 where
 | 
			
		||||
>
 | 
			
		||||
> import Data.Maybe (fromMaybe)
 | 
			
		||||
>
 | 
			
		||||
> import List
 | 
			
		||||
>
 | 
			
		||||
> import ERPSys
 | 
			
		||||
>
 | 
			
		||||
> import Aufgabe2
 | 
			
		||||
 | 
			
		||||
Die Funktion scan soll, aus einer `ProductList` (2. Argument) anhand eines
 | 
			
		||||
Barcodes (1. Argument) einen Artikel finden und diesen dann in eine 
 | 
			
		||||
Scannerliste einfügen. Wurde kein Artiekl gefunden gibt `scan` `Nothing` zurück.
 | 
			
		||||
Um die eigentliche Funktion `scan` zu implementieren, empfiehlt es sich, zuerst
 | 
			
		||||
eine Instanz `Eq` für `Article` zu definieren.
 | 
			
		||||
Diese sollte anhand des Barcodes die Gleichheit eines Artikels bestimmen.
 | 
			
		||||
 | 
			
		||||
> scan :: (Eq a) => a -> ProductList a b c -> ScannerList a b c -> Maybe (ScannerList a b c)
 | 
			
		||||
>
 | 
			
		||||
> scan = undefined
 | 
			
		||||
 | 
			
		||||
> instance (Eq a) => Eq (Article a b c) where
 | 
			
		||||
>
 | 
			
		||||
>  (==) = undefined
 | 
			
		||||
 | 
			
		||||
> result = show $ scan 1 productCatalog
 | 
			
		||||
>        $ fromMaybe AmountListEnd $ scan 2 productCatalog
 | 
			
		||||
>        $ fromMaybe AmountListEnd $ scan 1 productCatalog AmountListEnd
 | 
			
		||||
							
								
								
									
										31
									
								
								src/Aufgabe3.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/Aufgabe3.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
Aufgabe 3
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
> module Aufgabe3 where
 | 
			
		||||
>
 | 
			
		||||
> import Data.Maybe (fromMaybe)
 | 
			
		||||
>
 | 
			
		||||
> import List
 | 
			
		||||
>
 | 
			
		||||
> import ERPSys
 | 
			
		||||
>
 | 
			
		||||
> import Aufgabe2
 | 
			
		||||
 | 
			
		||||
Die Funktion scan soll, aus einer `ProductList` (2. Argument) anhand eines
 | 
			
		||||
Barcodes (1. Argument) einen Artikel finden und diesen dann in eine 
 | 
			
		||||
Scannerliste einfügen. Wurde kein Artiekl gefunden gibt `scan` `Nothing` zurück.
 | 
			
		||||
Um die eigentliche Funktion `scan` zu implementieren, empfiehlt es sich, zuerst
 | 
			
		||||
eine Instanz `Eq` für `Article` zu definieren.
 | 
			
		||||
Diese sollte anhand des Barcodes die Gleichheit eines Artikels bestimmen.
 | 
			
		||||
 | 
			
		||||
> scan :: (Eq a) => a -> ProductList a b c -> ScannerList a b c -> Maybe (ScannerList a b c)
 | 
			
		||||
>
 | 
			
		||||
> scan = undefined
 | 
			
		||||
 | 
			
		||||
> instance (Eq a) => Eq (Article a b c) where
 | 
			
		||||
>
 | 
			
		||||
>  (==) = undefined
 | 
			
		||||
 | 
			
		||||
> result = show $ scan 1 productCatalog
 | 
			
		||||
>        $ fromMaybe AmountListEnd $ scan 2 productCatalog
 | 
			
		||||
>        $ fromMaybe AmountListEnd $ scan 1 productCatalog AmountListEnd
 | 
			
		||||
							
								
								
									
										40
									
								
								src/Aufgabe4.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/Aufgabe4.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
-- Aufgabe 4
 | 
			
		||||
-- =========
 | 
			
		||||
 | 
			
		||||
module Aufgabe4 where
 | 
			
		||||
 | 
			
		||||
import Lib
 | 
			
		||||
import Aufgabe2
 | 
			
		||||
import Aufgabe3
 | 
			
		||||
import Data.Maybe (fromMaybe)
 | 
			
		||||
 | 
			
		||||
-- Nun da eine `ScannerList` erstellt werden kann, wird eine Funktion, die einen Kassenbon erstellen kann, benötigt.
 | 
			
		||||
-- Dieser sollte angemessen formatiert sein.
 | 
			
		||||
-- Die Funktion `generateBill` soll diese Aufgabe übernehmen.
 | 
			
		||||
 | 
			
		||||
type Bill = String
 | 
			
		||||
 
 | 
			
		||||
generateBill :: (Show a, Show b, Show c) => ScannerList a b c -> Bill
 | 
			
		||||
 | 
			
		||||
generateBill = undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
result = generateBill scannerList
 | 
			
		||||
 | 
			
		||||
-- Ein paar Hilfsfunktionen zum generieren einer `ScannerList` asu einer Liste
 | 
			
		||||
-- von Barcodes. /Glücklicherweise/ hat diese bereits ein Kollege von Ihnen entwickelt!
 | 
			
		||||
-- (Mit anderen Worten: Sie brauchen die unten stehenden Funktionen weder
 | 
			
		||||
-- anpassen, noch verstehen und auch nicht benutzen, nochmal Glück gehabt ;D )
 | 
			
		||||
 | 
			
		||||
scannerList :: ScannerList Int String Float
 | 
			
		||||
scannerList = fromMaybe AmountListEnd $ scanList [1,3,1,2,1,3]
 | 
			
		||||
 | 
			
		||||
scanList :: [Int] -> Maybe (ScannerList Int String Float)
 | 
			
		||||
scanList l = let help :: [Int] -> Maybe (ScannerList Int String Float) -> Maybe (ScannerList Int String Float)
 | 
			
		||||
                 help = flip $ foldl (\sl a -> sl >>= preparedScan a)
 | 
			
		||||
              in help l $ Just AmountListEnd
 | 
			
		||||
 | 
			
		||||
preparedScan :: Int -> ScannerList Int String Float -> Maybe (ScannerList Int String Float)
 | 
			
		||||
 | 
			
		||||
preparedScan = flip scan productCatalog
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								src/Aufgabe4.lhs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/Aufgabe4.lhs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
Aufgabe 4
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
> module Aufgabe4 where
 | 
			
		||||
>
 | 
			
		||||
> import Lib
 | 
			
		||||
> import Aufgabe2
 | 
			
		||||
> import Aufgabe3
 | 
			
		||||
> import Data.Maybe (fromMaybe)
 | 
			
		||||
 | 
			
		||||
Nun da eine `ScannerList` erstellt werden kann, wird eine Funktion, die einen Kassenbon erstellen kann, benötigt.
 | 
			
		||||
Dieser sollte /angemessen/ formatiert sein.
 | 
			
		||||
Die Funktion `generateBill` soll diese Aufgabe übernehmen.
 | 
			
		||||
 | 
			
		||||
> type Bill = String
 | 
			
		||||
>
 | 
			
		||||
> generateBill :: (Show a, Show b, Show c) => ScannerList a b c -> Bill
 | 
			
		||||
>
 | 
			
		||||
> generateBill = undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> result = generateBill scannerList
 | 
			
		||||
 | 
			
		||||
Ein paar Hilfsfunktionen zum generieren einer `ScannerList` asu einer Liste
 | 
			
		||||
von Barcodes. /Glücklicherweise/ hat diese bereits ein Kollege von Ihnen entwickelt!
 | 
			
		||||
(Mit anderen Worten: Sie brauchen die unten stehenden Funktionen weder
 | 
			
		||||
anpassen, noch verstehen und auch nicht benutzen, nochmal Glück gehabt ;D )
 | 
			
		||||
 | 
			
		||||
> scannerList :: ScannerList Int String Float
 | 
			
		||||
> scannerList = fromMaybe AmountListEnd $ scanList [1,3,1,2,1,3]
 | 
			
		||||
 | 
			
		||||
> scanList :: [Int] -> Maybe (ScannerList Int String Float)
 | 
			
		||||
> scanList l = let help :: [Int] -> Maybe (ScannerList Int String Float) -> Maybe (ScannerList Int String Float)
 | 
			
		||||
>                  help = flip $ foldl (\sl a -> sl >>= preparedScan a)
 | 
			
		||||
>               in help l $ Just AmountListEnd
 | 
			
		||||
 | 
			
		||||
> preparedScan :: Int -> ScannerList Int String Float -> Maybe (ScannerList Int String Float)
 | 
			
		||||
> 
 | 
			
		||||
> preparedScan = flip scan productCatalog
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								src/Aufgabe4.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/Aufgabe4.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
Aufgabe 4
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
> module Aufgabe4 where
 | 
			
		||||
>
 | 
			
		||||
> import Lib
 | 
			
		||||
> import Aufgabe2
 | 
			
		||||
> import Aufgabe3
 | 
			
		||||
> import Data.Maybe (fromMaybe)
 | 
			
		||||
 | 
			
		||||
Nun da eine `ScannerList` erstellt werden kann, wird eine Funktion, die einen Kassenbon erstellen kann, benötigt.
 | 
			
		||||
Dieser sollte /angemessen/ formatiert sein.
 | 
			
		||||
Die Funktion `generateBill` soll diese Aufgabe übernehmen.
 | 
			
		||||
 | 
			
		||||
> type Bill = String
 | 
			
		||||
>
 | 
			
		||||
> generateBill :: (Show a, Show b, Show c) => ScannerList a b c -> Bill
 | 
			
		||||
>
 | 
			
		||||
> generateBill = undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
> result = generateBill scannerList
 | 
			
		||||
 | 
			
		||||
Ein paar Hilfsfunktionen zum generieren einer `ScannerList` asu einer Liste
 | 
			
		||||
von Barcodes. /Glücklicherweise/ hat diese bereits ein Kollege von Ihnen entwickelt!
 | 
			
		||||
(Mit anderen Worten: Sie brauchen die unten stehenden Funktionen weder
 | 
			
		||||
anpassen, noch verstehen und auch nicht benutzen, nochmal Glück gehabt ;D )
 | 
			
		||||
 | 
			
		||||
> scannerList :: ScannerList Int String Float
 | 
			
		||||
> scannerList = fromMaybe AmountListEnd $ scanList [1,3,1,2,1,3]
 | 
			
		||||
 | 
			
		||||
> scanList :: [Int] -> Maybe (ScannerList Int String Float)
 | 
			
		||||
> scanList l = let help :: [Int] -> Maybe (ScannerList Int String Float) -> Maybe (ScannerList Int String Float)
 | 
			
		||||
>                  help = flip $ foldl (\sl a -> sl >>= preparedScan a)
 | 
			
		||||
>               in help l $ Just AmountListEnd
 | 
			
		||||
 | 
			
		||||
> preparedScan :: Int -> ScannerList Int String Float -> Maybe (ScannerList Int String Float)
 | 
			
		||||
> 
 | 
			
		||||
> preparedScan = flip scan productCatalog
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								src/ERPSys.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/ERPSys.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
module ERPSys
 | 
			
		||||
  ( ProductList
 | 
			
		||||
  , ScannerList
 | 
			
		||||
  , Article(Article)
 | 
			
		||||
  ) where
 | 
			
		||||
 | 
			
		||||
import List
 | 
			
		||||
 | 
			
		||||
type ProductList a b c = List (Article a b c) -- ^ List with Articles
 | 
			
		||||
type ScannerList a b c = AmountList Int (Article a b c) -- ^ AmountList with Articles
 | 
			
		||||
 | 
			
		||||
-- | generic Article isomorph to (,,)
 | 
			
		||||
data Article a b c = Article
 | 
			
		||||
 { _barcode :: a
 | 
			
		||||
 , _name    :: b
 | 
			
		||||
 , _price   :: c
 | 
			
		||||
 } deriving (Show)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								src/Lib.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/Lib.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
module Lib
 | 
			
		||||
  ( ProductList
 | 
			
		||||
  , ScannerList
 | 
			
		||||
  , Article(Article)
 | 
			
		||||
  , List(ListEnd, Element)
 | 
			
		||||
  , AmountList(AmountAndElement, AmountListEnd)
 | 
			
		||||
  , Filter
 | 
			
		||||
  , Searchable(..)
 | 
			
		||||
  , Consumable(..)
 | 
			
		||||
  , Insertable(..)
 | 
			
		||||
  ) where
 | 
			
		||||
 | 
			
		||||
import List
 | 
			
		||||
import ERPSys
 | 
			
		||||
							
								
								
									
										123
									
								
								src/List.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/List.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
{-# LANGUAGE MultiParamTypeClasses #-}
 | 
			
		||||
{-# LANGUAGE FlexibleInstances #-}
 | 
			
		||||
{-# LANGUAGE InstanceSigs #-}
 | 
			
		||||
{-# LANGUAGE FunctionalDependencies #-}
 | 
			
		||||
{-# LANGUAGE TemplateHaskell #-}
 | 
			
		||||
 | 
			
		||||
module List
 | 
			
		||||
  ( List(ListEnd, Element)
 | 
			
		||||
  , AmountList(AmountAndElement, AmountListEnd)
 | 
			
		||||
  , Filter
 | 
			
		||||
  , Searchable(..)
 | 
			
		||||
  , Consumable(..)
 | 
			
		||||
  , Insertable(..)
 | 
			
		||||
--  , amountOf
 | 
			
		||||
  ) where
 | 
			
		||||
 | 
			
		||||
import Control.Lens
 | 
			
		||||
import Data.Maybe (fromMaybe)
 | 
			
		||||
 | 
			
		||||
-- | isomorph to []
 | 
			
		||||
data List a = ListEnd | Element
 | 
			
		||||
  { _el        :: a 
 | 
			
		||||
  , _remaining :: (List a)
 | 
			
		||||
  } deriving (Show)
 | 
			
		||||
 | 
			
		||||
makeLenses (''List)
 | 
			
		||||
 | 
			
		||||
-- | counting list
 | 
			
		||||
data AmountList a b = AmountListEnd | AmountAndElement
 | 
			
		||||
  { _amount     :: a
 | 
			
		||||
  , _el'        :: b 
 | 
			
		||||
  , _remaining' :: (AmountList a b)
 | 
			
		||||
  } deriving (Show)
 | 
			
		||||
 | 
			
		||||
makeLenses (''AmountList)
 | 
			
		||||
 | 
			
		||||
type Filter a = a -> Bool
 | 
			
		||||
 | 
			
		||||
instance Monoid (List a) where
 | 
			
		||||
  mempty  = ListEnd
 | 
			
		||||
  mappend ListEnd = id
 | 
			
		||||
  mappend a = mappend $ a ^. remaining
 | 
			
		||||
 | 
			
		||||
instance Monoid (AmountList a b) where
 | 
			
		||||
  mempty  = AmountListEnd
 | 
			
		||||
  mappend AmountListEnd = id
 | 
			
		||||
  mappend a = mappend $ a ^. remaining'
 | 
			
		||||
 | 
			
		||||
instance Eq a => Eq (List a) where
 | 
			
		||||
  ListEnd == ListEnd = True
 | 
			
		||||
  a == b =  a^?el         == b^?el
 | 
			
		||||
         && a^?remaining  == b^?remaining
 | 
			
		||||
 | 
			
		||||
instance (Eq a, Eq b) => Eq (AmountList a b) where
 | 
			
		||||
  AmountListEnd == AmountListEnd = True
 | 
			
		||||
  a == b =  a^?amount     == b^?amount
 | 
			
		||||
         && a^?el'        == b^?el'
 | 
			
		||||
         && a^?remaining' == b^?remaining'
 | 
			
		||||
 | 
			
		||||
-- | find with return type determined by the structure b a
 | 
			
		||||
class Searchable a b c | b a -> c where
 | 
			
		||||
  findFirst :: Filter a -> b a -> Maybe c
 | 
			
		||||
 | 
			
		||||
-- | find first a in list matching the filter
 | 
			
		||||
instance Searchable a List a where
 | 
			
		||||
  findFirst :: Filter a -> List a -> Maybe a
 | 
			
		||||
  findFirst filter list = list^?el>>=(\el_-> if filter el_ 
 | 
			
		||||
                                             then Just el_ 
 | 
			
		||||
                                             else findFirst filter $ list^.remaining)
 | 
			
		||||
 | 
			
		||||
-- | find first a in list matching the filter returning (amount, element)
 | 
			
		||||
instance Searchable a (AmountList b) (b, a) where
 | 
			
		||||
  findFirst :: Filter a -> AmountList b a -> Maybe (b, a)
 | 
			
		||||
  findFirst filter list = list^?el' >>= \el_ -> if filter el_ 
 | 
			
		||||
                                                then Just (list^?!amount, el_) 
 | 
			
		||||
                                                else list^?remaining' >>= findFirst filter
 | 
			
		||||
 | 
			
		||||
class Consumable b a c | b a -> c  where
 | 
			
		||||
  consume :: (c -> d -> d) -> d -> b a -> d
 | 
			
		||||
  -- ^ special form of a fold determined by structure b a
 | 
			
		||||
 | 
			
		||||
-- | isomorph to a foldr
 | 
			
		||||
instance Consumable List a a where
 | 
			
		||||
  consume :: (a -> d -> d) -> d -> List a -> d
 | 
			
		||||
  consume _ a ListEnd = a
 | 
			
		||||
  consume f s (Element a as) = f a $ consume f s as
 | 
			
		||||
 | 
			
		||||
-- | foldr over (element, amount)
 | 
			
		||||
instance Consumable (AmountList b) a (a, b) where
 | 
			
		||||
  consume :: ((a, b) -> e -> e) -> e -> AmountList b a -> e
 | 
			
		||||
  consume _ a AmountListEnd = a
 | 
			
		||||
  consume f s (AmountAndElement b a as) = f (a,b) $ consume f s as
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{--instance {-# OVERLAPPABLE #-} Consumable (AmountList b) a a where
 | 
			
		||||
  consume :: (a -> e -> e) -> e -> AmountList b a -> e
 | 
			
		||||
  consume _ a AmountListEnd = a
 | 
			
		||||
  consume f s (AmountAndElement b a as) = f a $ consume f s as --}
 | 
			
		||||
 | 
			
		||||
class Insertable a b where
 | 
			
		||||
  insert :: a -> b a -> b a
 | 
			
		||||
  -- ^ insert a to structure b
 | 
			
		||||
 | 
			
		||||
-- | RTFC!
 | 
			
		||||
instance Insertable a List where
 | 
			
		||||
  insert :: a -> List a -> List a
 | 
			
		||||
  insert = Element
 | 
			
		||||
 | 
			
		||||
-- | insert with amount count += 1
 | 
			
		||||
instance (Eq a, Num b) => Insertable a (AmountList b) where
 | 
			
		||||
  insert :: a -> AmountList b a -> AmountList b a
 | 
			
		||||
  insert a AmountListEnd = AmountAndElement 1 a AmountListEnd
 | 
			
		||||
  insert a b = case b^?el' & _Just %~ (==a) of
 | 
			
		||||
    Just True -> b & amount +~ 1
 | 
			
		||||
    _         -> b & remaining' %~ (insert a)
 | 
			
		||||
 | 
			
		||||
-- | get amount of a in list. returning mempty if not found
 | 
			
		||||
amountOf :: (Eq a, Monoid b) => a -> AmountList b a -> b
 | 
			
		||||
amountOf a b = fromMaybe mempty $ b ^. to (findFirst (==a)) & _Just %~ fst
 | 
			
		||||
--b ^. to findFirst (==a) %~ _1 ^. to fromMaybe mempty 
 | 
			
		||||
--  (Just (c,_)) -> c
 | 
			
		||||
--  Nothing      -> mempty
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										66
									
								
								stack.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								stack.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
# This file was automatically generated by 'stack init'
 | 
			
		||||
# 
 | 
			
		||||
# Some commonly used options have been documented as comments in this file.
 | 
			
		||||
# For advanced use and comprehensive documentation of the format, please see:
 | 
			
		||||
# http://docs.haskellstack.org/en/stable/yaml_configuration/
 | 
			
		||||
 | 
			
		||||
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
 | 
			
		||||
# A snapshot resolver dictates the compiler version and the set of packages
 | 
			
		||||
# to be used for project dependencies. For example:
 | 
			
		||||
# 
 | 
			
		||||
# resolver: lts-3.5
 | 
			
		||||
# resolver: nightly-2015-09-21
 | 
			
		||||
# resolver: ghc-7.10.2
 | 
			
		||||
# resolver: ghcjs-0.1.0_ghc-7.10.2
 | 
			
		||||
# resolver:
 | 
			
		||||
#  name: custom-snapshot
 | 
			
		||||
#  location: "./custom-snapshot.yaml"
 | 
			
		||||
resolver: lts-8.12
 | 
			
		||||
 | 
			
		||||
# User packages to be built.
 | 
			
		||||
# Various formats can be used as shown in the example below.
 | 
			
		||||
# 
 | 
			
		||||
# packages:
 | 
			
		||||
# - some-directory
 | 
			
		||||
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
 | 
			
		||||
# - location:
 | 
			
		||||
#    git: https://github.com/commercialhaskell/stack.git
 | 
			
		||||
#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
 | 
			
		||||
# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
 | 
			
		||||
#   extra-dep: true
 | 
			
		||||
#  subdirs:
 | 
			
		||||
#  - auto-update
 | 
			
		||||
#  - wai
 | 
			
		||||
# 
 | 
			
		||||
# A package marked 'extra-dep: true' will only be built if demanded by a
 | 
			
		||||
# non-dependency (i.e. a user package), and its test suites and benchmarks
 | 
			
		||||
# will not be run. This is useful for tweaking upstream packages.
 | 
			
		||||
packages:
 | 
			
		||||
- '.'
 | 
			
		||||
# Dependency packages to be pulled from upstream that are not in the resolver
 | 
			
		||||
# (e.g., acme-missiles-0.3)
 | 
			
		||||
extra-deps: []
 | 
			
		||||
 | 
			
		||||
# Override default flag values for local packages and extra-deps
 | 
			
		||||
flags: {}
 | 
			
		||||
 | 
			
		||||
# Extra package databases containing global packages
 | 
			
		||||
extra-package-dbs: []
 | 
			
		||||
 | 
			
		||||
# Control whether we use the GHC we find on the path
 | 
			
		||||
# system-ghc: true
 | 
			
		||||
# 
 | 
			
		||||
# Require a specific version of stack, using version ranges
 | 
			
		||||
# require-stack-version: -any # Default
 | 
			
		||||
# require-stack-version: ">=1.1"
 | 
			
		||||
# 
 | 
			
		||||
# Override the architecture used by stack, especially useful on Windows
 | 
			
		||||
# arch: i386
 | 
			
		||||
# arch: x86_64
 | 
			
		||||
# 
 | 
			
		||||
# Extra directories used by stack for building
 | 
			
		||||
# extra-include-dirs: [/path/to/dir]
 | 
			
		||||
# extra-lib-dirs: [/path/to/dir]
 | 
			
		||||
# 
 | 
			
		||||
# Allow a newer minor version of GHC than the snapshot specifies
 | 
			
		||||
# compiler-check: newer-minor
 | 
			
		||||
							
								
								
									
										17
									
								
								test/Aufgabe1-Spec.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								test/Aufgabe1-Spec.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
import Aufgabe1
 | 
			
		||||
 | 
			
		||||
import Test.Framework.Providers.HUnit (testCase)
 | 
			
		||||
import Test.Framework.Runners.Console (defaultMain)
 | 
			
		||||
 | 
			
		||||
import Test.HUnit
 | 
			
		||||
 | 
			
		||||
test1 = testCase "filter funktioniert" $ assertEqual "Vowel filter" "Hll Wrld!" result
 | 
			
		||||
 | 
			
		||||
testSentence2 = "Is really EVERY VowEL of this uSEleSS SentencE remOved?"
 | 
			
		||||
testResult2 = "s rlly VRY VwL f ths SlSS Sntnc rmvd?"
 | 
			
		||||
test2 = testCase "filter test" $ assertEqual testSentence2 testResult2 $ filterVowels testSentence2 
 | 
			
		||||
 | 
			
		||||
tests = [test1, test2]
 | 
			
		||||
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = defaultMain tests
 | 
			
		||||
							
								
								
									
										40
									
								
								test/Aufgabe2-Spec.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								test/Aufgabe2-Spec.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
import Aufgabe2
 | 
			
		||||
 | 
			
		||||
import Test.Framework.Providers.HUnit (testCase)
 | 
			
		||||
import Test.Framework.Runners.Console (defaultMain)
 | 
			
		||||
 | 
			
		||||
import Test.HUnit
 | 
			
		||||
 | 
			
		||||
import Lib
 | 
			
		||||
 | 
			
		||||
instance (Eq a, Eq b, Eq c) => Eq (Article a b c) where
 | 
			
		||||
  (Article a b c) == (Article a' b' c') = a == a' && b == b' && c == c'
 | 
			
		||||
 | 
			
		||||
data TestProd = Tp1 | Tp2 | Tp3 deriving (Eq, Show)
 | 
			
		||||
 | 
			
		||||
emptyProductList :: ProductList Int () ()
 | 
			
		||||
emptyProductList = ListEnd
 | 
			
		||||
 | 
			
		||||
productList :: ProductList Int TestProd ()
 | 
			
		||||
productList = insert (Article 0 Tp1 ())
 | 
			
		||||
            $ insert (Article 1 Tp2 ())
 | 
			
		||||
            $ insert (Article 2 Tp3 ())
 | 
			
		||||
            $ ListEnd
 | 
			
		||||
 | 
			
		||||
emptyFind = testCase "Suche in leerer Liste"
 | 
			
		||||
          $ assertEqual "empty list search" Nothing
 | 
			
		||||
          $ findArticle 0 emptyProductList
 | 
			
		||||
 | 
			
		||||
findNone = testCase "Suche nach nicht vorhandenem"
 | 
			
		||||
         $ assertEqual "find nothing" Nothing 
 | 
			
		||||
         $ findArticle 3 productList
 | 
			
		||||
 | 
			
		||||
findSome = testCase "Suche nach vorhandenem"
 | 
			
		||||
         $ assertEqual "find some" (Just $ Article 0 Tp1 ()) 
 | 
			
		||||
         $ findArticle 0 productList
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
tests = [emptyFind, findNone, findSome]
 | 
			
		||||
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = defaultMain tests
 | 
			
		||||
							
								
								
									
										63
									
								
								test/Aufgabe3-Spec.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								test/Aufgabe3-Spec.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
import Aufgabe3
 | 
			
		||||
 | 
			
		||||
import Test.Framework.Providers.HUnit (testCase)
 | 
			
		||||
import Test.Framework.Runners.Console (defaultMain)
 | 
			
		||||
 | 
			
		||||
import Test.HUnit
 | 
			
		||||
 | 
			
		||||
import Lib
 | 
			
		||||
 | 
			
		||||
data TestProd = Tp1 | Tp2 | Tp3 deriving (Eq, Show)
 | 
			
		||||
 | 
			
		||||
productList :: ProductList Int TestProd ()
 | 
			
		||||
productList = insert (Article 0 Tp1 ())
 | 
			
		||||
            $ insert (Article 1 Tp2 ())
 | 
			
		||||
            $ insert (Article 2 Tp3 ())
 | 
			
		||||
            $ ListEnd
 | 
			
		||||
 | 
			
		||||
emptyScannerList :: ScannerList Int TestProd ()
 | 
			
		||||
emptyScannerList = AmountListEnd
 | 
			
		||||
 | 
			
		||||
scannerList1 = scan 0 productList emptyScannerList
 | 
			
		||||
scannerList2 = scan 9 productList emptyScannerList
 | 
			
		||||
scannerList3 = scannerList1 >>= scan 0 productList
 | 
			
		||||
scannerList4 = scannerList3 >>= scan 1 productList
 | 
			
		||||
scannerList5 = scannerList4 >>= scan 2 productList
 | 
			
		||||
scannerList6 = scannerList5 >>= scan 9 productList
 | 
			
		||||
scannerList7 = scannerList5 >>= scan 1 productList 
 | 
			
		||||
scannerList8 = scannerList7 >>= scan 0 productList
 | 
			
		||||
scannerList9 = scannerList8 >>= scan 9 productList
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
scan1 = testCase "Scan,     existing product, list size: 0                         "
 | 
			
		||||
      $ assertEqual "scan 1" (Just $ AmountAndElement 1 (Article 0 Tp1 ()) AmountListEnd) scannerList1
 | 
			
		||||
 | 
			
		||||
scan2 = testCase "Scan, not existing product, list size: 0                         "
 | 
			
		||||
      $ assertEqual "scan 2" Nothing scannerList2
 | 
			
		||||
 | 
			
		||||
scan3 = testCase "Scan,     existing product, list size: 1, product already in list"
 | 
			
		||||
      $ assertEqual "scan 3" (Just $ AmountAndElement 2 (Article 0 Tp1 ()) AmountListEnd) scannerList3
 | 
			
		||||
 | 
			
		||||
scan4 = testCase "Scan,     existing product, list size: 1, product not in list    "
 | 
			
		||||
      $ assertEqual "scan 4" (Just $ AmountAndElement 2 (Article 0 Tp1 ()) $ AmountAndElement 1 (Article 1 Tp2 ()) AmountListEnd) scannerList4
 | 
			
		||||
 | 
			
		||||
scan5 = testCase "Scan,     existing product, list size: 2, product not in list    "
 | 
			
		||||
      $ assertEqual "scan 5" (Just $ AmountAndElement 2 (Article 0 Tp1 ()) $ AmountAndElement 1 (Article 1 Tp2 ()) $ AmountAndElement 1 (Article 2 Tp3 ()) AmountListEnd) scannerList5
 | 
			
		||||
 | 
			
		||||
scan6 = testCase "Scan, not existing product, list size: 2                         "
 | 
			
		||||
      $ assertEqual "scan 3" Nothing scannerList6
 | 
			
		||||
 | 
			
		||||
scan7 = testCase "Scan,     existing product, list size: 3, product in list        "
 | 
			
		||||
      $ assertEqual "scan 7" (Just $ AmountAndElement 2 (Article 0 Tp1 ()) $ AmountAndElement 2 (Article 1 Tp2 ()) $ AmountAndElement 1 (Article 2 Tp3 ()) AmountListEnd) scannerList7
 | 
			
		||||
 | 
			
		||||
scan8 = testCase "Scan,     existing product, list size: 3, product in list        "
 | 
			
		||||
      $ assertEqual "scan 8" (Just $ AmountAndElement 3 (Article 0 Tp1 ()) $ AmountAndElement 2 (Article 1 Tp2 ()) $ AmountAndElement 1 (Article 2 Tp3 ()) AmountListEnd) scannerList8
 | 
			
		||||
 | 
			
		||||
scan9 = testCase "Scan, not existing product, list size: 3                         "
 | 
			
		||||
      $ assertEqual "scan 9" Nothing scannerList9
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
tests = [scan1, scan2, scan3, scan4, scan5, scan6, scan7, scan8, scan9]
 | 
			
		||||
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = defaultMain tests
 | 
			
		||||
							
								
								
									
										4
									
								
								test/Aufgabe4-Spec.hs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								test/Aufgabe4-Spec.hs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
main :: IO ()
 | 
			
		||||
main = do
 | 
			
		||||
  putStrLn "Da Ihnen in dieser Aufgabe Platz für Kreativität eingeräumt wurde,"
 | 
			
		||||
  putStrLn "lässt sich Ihre Lösung leider nicht automatisiert überprüfen."
 | 
			
		||||
							
								
								
									
										111
									
								
								zettel1.cabal
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								zettel1.cabal
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
name:                zettel1
 | 
			
		||||
version:             0.1.0.0
 | 
			
		||||
synopsis:            First Assignment of FFPiHaskell 2017
 | 
			
		||||
-- description:
 | 
			
		||||
homepage:            https://github.com/FFPiHaskell/zettel1-skeleton#readme
 | 
			
		||||
license:             BSD3
 | 
			
		||||
license-file:        LICENSE
 | 
			
		||||
author:              FFPiHaskell Tutors
 | 
			
		||||
maintainer:          sdressel@techfak.uni-bielefeld.de
 | 
			
		||||
copyright:           2017 FFPiHaskell Tutors
 | 
			
		||||
category:            cli
 | 
			
		||||
build-type:          Simple
 | 
			
		||||
extra-source-files:  README.md
 | 
			
		||||
cabal-version:       >=1.10
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- library for all things common in all exercises/not neccessary for students
 | 
			
		||||
-- to solve assignments
 | 
			
		||||
library
 | 
			
		||||
  hs-source-dirs:      src
 | 
			
		||||
  exposed-modules:     Lib
 | 
			
		||||
                     , Aufgabe1
 | 
			
		||||
                     , Aufgabe2
 | 
			
		||||
                     , Aufgabe3
 | 
			
		||||
                     , Aufgabe4
 | 
			
		||||
                     , List
 | 
			
		||||
                     , ERPSys
 | 
			
		||||
  build-depends:       base >= 4.7 && < 5
 | 
			
		||||
                     , lens
 | 
			
		||||
  default-language:    Haskell2010
 | 
			
		||||
 | 
			
		||||
executable aufgabe1
 | 
			
		||||
  hs-source-dirs:      app
 | 
			
		||||
  main-is:             Aufgabe1Main.hs
 | 
			
		||||
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
			
		||||
  build-depends:       base
 | 
			
		||||
                     , zettel1
 | 
			
		||||
  default-language:    Haskell2010
 | 
			
		||||
 | 
			
		||||
test-suite aufgabe1-tests
 | 
			
		||||
  type:                exitcode-stdio-1.0
 | 
			
		||||
  hs-source-dirs:      test
 | 
			
		||||
  main-is:             Aufgabe1-Spec.hs
 | 
			
		||||
  build-depends:       base
 | 
			
		||||
                     , zettel1
 | 
			
		||||
                     , test-framework
 | 
			
		||||
                     , test-framework-hunit
 | 
			
		||||
                     , HUnit
 | 
			
		||||
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
			
		||||
  default-language:    Haskell2010
 | 
			
		||||
 | 
			
		||||
executable aufgabe2
 | 
			
		||||
  hs-source-dirs:      app
 | 
			
		||||
  main-is:             Aufgabe2Main.hs
 | 
			
		||||
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
			
		||||
  build-depends:       base
 | 
			
		||||
                     , zettel1
 | 
			
		||||
  default-language:    Haskell2010
 | 
			
		||||
 | 
			
		||||
test-suite aufgabe2-tests
 | 
			
		||||
  type:                exitcode-stdio-1.0
 | 
			
		||||
  hs-source-dirs:      test
 | 
			
		||||
  main-is:             Aufgabe2-Spec.hs
 | 
			
		||||
  build-depends:       base
 | 
			
		||||
                     , zettel1
 | 
			
		||||
                     , test-framework
 | 
			
		||||
                     , test-framework-hunit
 | 
			
		||||
                     , HUnit
 | 
			
		||||
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
			
		||||
  default-language:    Haskell2010
 | 
			
		||||
 | 
			
		||||
executable aufgabe3
 | 
			
		||||
  hs-source-dirs:      app
 | 
			
		||||
  main-is:             Aufgabe3Main.hs
 | 
			
		||||
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
			
		||||
  build-depends:       base
 | 
			
		||||
                     , zettel1
 | 
			
		||||
  default-language:    Haskell2010
 | 
			
		||||
 | 
			
		||||
test-suite aufgabe3-tests
 | 
			
		||||
  type:                exitcode-stdio-1.0
 | 
			
		||||
  hs-source-dirs:      test
 | 
			
		||||
  main-is:             Aufgabe3-Spec.hs
 | 
			
		||||
  build-depends:       base
 | 
			
		||||
                     , zettel1
 | 
			
		||||
                     , test-framework
 | 
			
		||||
                     , test-framework-hunit
 | 
			
		||||
                     , HUnit
 | 
			
		||||
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
			
		||||
  default-language:    Haskell2010
 | 
			
		||||
 | 
			
		||||
executable aufgabe4
 | 
			
		||||
  hs-source-dirs:      app
 | 
			
		||||
  main-is:             Aufgabe4Main.hs
 | 
			
		||||
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
			
		||||
  build-depends:       base
 | 
			
		||||
                     , zettel1
 | 
			
		||||
  default-language:    Haskell2010
 | 
			
		||||
 | 
			
		||||
test-suite aufgabe4-tests
 | 
			
		||||
  type:                exitcode-stdio-1.0
 | 
			
		||||
  hs-source-dirs:      test
 | 
			
		||||
  main-is:             Aufgabe4-Spec.hs
 | 
			
		||||
  build-depends:       base
 | 
			
		||||
                     , zettel1
 | 
			
		||||
  ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 | 
			
		||||
  default-language:    Haskell2010
 | 
			
		||||
 | 
			
		||||
source-repository head
 | 
			
		||||
  type:     git
 | 
			
		||||
  location: https://github.com/FFPiHaskell/zettel1-skeleton
 | 
			
		||||
		Reference in New Issue
	
	Block a user