EX1: Typos etc.

This commit is contained in:
Jonas Betzendahl 2016-04-17 17:56:36 +02:00
parent ec27b6a417
commit b701278f87
No known key found for this signature in database
GPG Key ID: C64D686FC97D4B2D

View File

@ -2,7 +2,7 @@
## Typtheorie ## Typtheorie
Schreiben sie alle **möglichen** Implementationen der folgenden Funktionen. Wozu könnte `fun2` nützlich sein? Schreiben Sie alle **möglichen** Implementationen der folgenden Funktionen. Wozu könnte `fun2` nützlich sein?
```haskell ```haskell
fun1 :: a -> a fun1 :: a -> a
@ -15,13 +15,13 @@ fun3 :: (Eq a) => a -> a -> Bool
fun3 = _fun3 fun3 = _fun3
``` ```
Wir haben in der Vorlesung parametrisierte Typen kennengelernt. Der simpelste hiervon ist `Identity`, der genau gar nichts macht, sondern nur einen anderen Typen einpackt. Wir haben in der Vorlesung parametrisierte Typen kennengelernt. Der simpelste hiervon ist `Identity`, der nur einen anderen Typen einpackt.
```haskell ```haskell
data Identity a = Identity a data Identity a = Identity a
``` ```
Diese Definition stellt uns automatisch den Konstruktor `Identity :: a -> Identity a` zur Verfügung, der ein `a` einpackt. Schreiben sie die Funktion Diese Definition stellt uns automatisch den Konstruktor `Identity :: a -> Identity a` zur Verfügung, der ein `a` einpackt. Schreiben Sie die Funktion
```haskell ```haskell
unIdentity :: Identity a -> a unIdentity :: Identity a -> a
@ -30,19 +30,19 @@ unIdentity = _unIdentity
welche diesen Vorgang wieder rückgängig macht. welche diesen Vorgang wieder rückgängig macht.
Angenommen, sie hätten nun ein Wert vom Typen `Identity a` und eine Funktion mit dem Typen `a -> b`. Wie wenden sie diese auf das `a` "innerhalb" des `Identity` an um ein `Identity b` herzustellen? Schreiben sie also eine Funktion Angenommen, Sie hätten nun ein Wert vom Typen `Identity a` und eine Funktion mit dem Typen `a -> b`. Wie wenden Sie diese auf das `a` "innerhalb" des `Identity` an um ein `Identity b` herzustellen? Schreiben Sie also eine Funktion
```haskell ```haskell
mapIdentity :: (a -> b) -> Identity a -> Identity b mapIdentity :: (a -> b) -> Identity a -> Identity b
mapIdentity = _mapIdentity mapIdentity = _mapIdentity
``` ```
**Hinweis:** Es gibt *zwei* prinzipielle Vorgehen dieses zu implementieren. Kommen sie auf beide? **Hinweis:** Es gibt *zwei* prinzipielle Vorgehen dieses zu implementieren. Kommen Sie auf beide?
## Funktionen sind auch nur Typen ## Funktionen sind auch nur Typen
Datentypen können auch Funktionen enthalten. Sehen sie sich einmal den Datentype Datentypen können auch Funktionen enthalten. Sehen Sie sich einmal den Datentypen
```haskell ```haskell
data Pred a = Pred (a -> Bool) data Pred a = Pred (a -> Bool)
@ -50,19 +50,19 @@ data Pred a = Pred (a -> Bool)
an. Hier wird ein Prädikat definiert, welches (gegeben einen Datentyp `a`) eine Funktion gespeichert hat, die `a` in einen `Bool` umwandeln kann (etwa um irgendwas zu filtern/selektieren/löschen/..., wenn man dies an eine weitere Funktion übergibt). an. Hier wird ein Prädikat definiert, welches (gegeben einen Datentyp `a`) eine Funktion gespeichert hat, die `a` in einen `Bool` umwandeln kann (etwa um irgendwas zu filtern/selektieren/löschen/..., wenn man dies an eine weitere Funktion übergibt).
Auch hier können sei eine Funktion schreiben, die das `Pred a` wieder "auspackt". Definieren sie Auch hier können Sie eine Funktion schreiben, die das `Pred a` wieder "auspackt". Definieren Sie
```haskell ```haskell
unPred :: Pred a -> (a -> Bool) unPred :: Pred a -> (a -> Bool)
unPred = _unPred unPred = _unPred
``` ```
Da Haskell-Funktionen aber "gecurried" sind, 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. Da Haskell-Funktionen aber "gecurried" sind (mehr dazu in der Vorlesung), 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.
In der Tat sind beide Funktionen identisch (wieso?). In der Tat sind beide Funktionen identisch (wieso?).
### Bonus ### Bonus
Was für eine Funktion bräuchten sie um ein `Pred a` in ein `Pred b` umzuwandeln? Können sie diese Implementieren? Was für eine Funktion bräuchten Sie um ein `Pred a` in ein `Pred b` umzuwandeln? Können Sie diese implementieren?
```haskell ```haskell
mapPred :: _fun -> Pred a -> Pred b mapPred :: _fun -> Pred a -> Pred b
@ -71,13 +71,13 @@ mapPred = _mapPred
## Neue Typen erfinden ## Neue Typen erfinden
In Haskell ist ein zentraler Vorgehenspunkt das Definieren und Verwenden von eigenen Datentypen. Zur Erinnerung; es gibt 2 Möglichkeiten, die man miteinander kombinieren kann: `data Prod a b c = Prod a b c` benötigt sowohl `a`, `b` als auch `c` um einen Wert zu erzeugen, `data Sum a b = Sum1 a | Sum2 b` braucht entweder ein `a` um durch den Konstruktor `Sum1` ein `Sum a b` zu erzeugen oder ein `b` um durch den Konstruktor `Sum2` ein `Sum a b` zu erzeugen. In Haskell ist ein zentraler Vorgehenspunkt das Definieren und Verwenden von eigenen Datentypen. Zur Erinnerung; es gibt zwei Möglichkeiten, die man miteinander kombinieren kann: `data Prod a b c = Prod a b c` (Produkttyp) benötigt sowohl `a`, `b` als auch `c` um einen Wert zu erzeugen, `data Sum a b = Sum1 a | Sum2 b` (Summentyp) braucht entweder ein `a` um durch den Konstruktor `Sum1` ein `Sum a b` zu erzeugen oder ein `b` um durch den Konstruktor `Sum2` ein `Sum a b` zu erzeugen.
Definieren sie einen Datentypen `Vielleicht a`, der zwei Konstruktoren besitzt: Einen Konstruktor, der durch ein `a` ein `Vielleicht a` konstruiert wird und ein zweiter Konstruktor, der keinen Wert nimmt, sondern die "Abwesenheit eines `a`" symbolisieren soll. Definieren Sie einen Datentypen `Vielleicht a`, der zwei Konstruktoren besitzt: Einen Konstruktor, mit dem durch ein `a` ein `Vielleicht a` konstruiert wird und ein zweiter Konstruktor, der keinen Wert nimmt, sondern die "Abwesenheit eines `a`" symbolisieren soll.
Können sie hier eine Funktion schreiben, die das `a` extrahiert? Wenn ja, implementieren sie diese; wenn nein, geben sie eine kurze Begründung. Können Sie hier eine Funktion schreiben, die das `a` extrahiert? Wenn ja, implementieren Sie diese; wenn nein, geben Sie eine kurze Begründung.
Wie würden sie mittels einer Funktion `a -> b` ein `Vielleicht a` in ein `Vielleicht b` wandeln? Implementieren sie Wie würden Sie mittels einer Funktion `a -> b` ein `Vielleicht a` in ein `Vielleicht b` wandeln? Implementieren Sie
```haskell ```haskell
mapVielleicht :: (a -> b) -> Vielleicht a -> Vielleicht b mapVielleicht :: (a -> b) -> Vielleicht a -> Vielleicht b
mapVielleicht = _mapVielleicht mapVielleicht = _mapVielleicht
@ -85,9 +85,6 @@ mapVielleicht = _mapVielleicht
### Bonus ### Bonus
Man kann Typen natürlich auch Schachteln. Worin liegt eigentlich der Unterschied zwischen einem `Pred (Vielleicht a)` und einem `Vielleicht (Pred a)`? Oder sind diese Identisch? Man kann Typen natürlich auch Schachteln. Worin liegt eigentlich der Unterschied zwischen einem `Pred (Vielleicht a)` und einem `Vielleicht (Pred a)`? Oder sind diese identisch?