Skip to content
Snippets Groups Projects
Commit 9ba10392 authored by Yannick Gottschalk's avatar Yannick Gottschalk
Browse files

initial commit

parents
No related branches found
No related tags found
No related merge requests found
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
*~
# 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
LICENSE 0 → 100644
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.
\ No newline at end of file
README.md 0 → 100644
Ü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
import Distribution.Simple
main = defaultMain
module Main where
import Aufgabe1
main :: IO ()
main = putStrLn result
module Main where
import Aufgabe2
main :: IO ()
main = putStrLn result
module Main where
import Aufgabe3
main :: IO ()
main = putStrLn result
module Main where
import Aufgabe4
main :: IO ()
main = putStrLn result
{-
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!"
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!"
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!"
-- 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
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
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
-- 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
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
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
-- 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
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment