diff --git a/Übungen/Blatt3.hs b/Übungen/Blatt3.hs new file mode 100644 index 0000000..1f946ed --- /dev/null +++ b/Übungen/Blatt3.hs @@ -0,0 +1,113 @@ +-- Übungsblatt 3 +-- ============= +-- +-- Throat-Clearing +-- --------------- +-- +-- a.k.a. Imports, damit der Code funktioniert. + +module MonadExercise where +import Control.Applicative +import Control.Monad +import Data.Monoid + +-- Vorwort +-- ------- +-- +-- Die Typklassen, die auf diesem Zettel implementiert werden sollen sind +-- teilweise nicht eindeutig. Ein gutes *Indiz* für eine falsche +-- implementation kann sein, dass Informationen "weggeschmissen" werden - +-- allerdings muss man bei anderen Implementationen genau dies machen. +-- +-- Applicative +-- ----------- +-- +-- Nachdem wir uns letzte Woche ausführlich mit der Typklasse `Functor` +-- beschäftigt haben, bauen wir nun darauf auf und definieren die +-- Applicative-Instanz. Zur Erinnerung: +-- +-- class Functor f => Applicative f where +-- pure :: a -> f a +-- <*> :: f (a -> b) -> f a -> f b +-- +-- Nehmen sie an, sie hätten folgende Datentypen mit ihren +-- `Functor`-Instanzen gegeben. Schreiben sie jeweils die +-- Applicative-Instanz: + +data Identity a = Identity { unIdentity :: a } + deriving (Show, Eq) + +instance Functor Identity where + fmap f (Identity a) = Identity (f a) + +data Vielleicht a = Etwas a + | Nichts + deriving (Show, Eq) + +instance Functor Vielleicht where + fmap f (Etwas a) = Etwas (f a) + fmap _ Nichts = Nichts + +data EntwederOder b a = Entweder a + | Oder b + deriving (Show, Eq) + +instance Functor (EntwederOder b) where + fmap f (Entweder a) = Entweder (f a) + fmap _ (Oder b) = Oder b + +data List a = Cons a (List a) + | Nil + deriving (Show, Eq) + +instance Functor List where + fmap f (Cons a r) = Cons (f a) (fmap f r) + fmap _ Nil = Nil + +instance Monoid (List a) where + mempty = Nil + mappend Nil bs = bs + mappend (Cons a as) bs = Cons a (mappend as bs) + +data V3 a = V3 a a a + +instance Functor V3 where + fmap f (V3 x y z) = V3 (f x) (f y) (f z) + +-- Monad +-- ----- +-- +-- Zu welchen der oben aufgeführten Typen gibt es eine Monaden-Instanz? Wie +-- sieht diese aus? Schreiben sie diese (falls möglich). +-- +-- Bonus +-- ----- + +data Account = Account +data Inbox = Inbox +data Mail = Mail + +-- Seien folgende Funktionen gegeben: + +login :: Maybe Account +login = undefined + +getInbox :: Account -> Maybe Inbox +getInbox = undefined + +getMails :: Inbox -> [Mail] +getMails = undefined + +safeHead :: [a] -> Maybe a +safeHead = undefined + +-- Schreiben sie eine Funktion: + +getFirstMail :: Maybe Mail +getFirstMail = undefined + +-- welche die oben genannten 4 Funktionen nutzt um die erste Mail aus dem +-- gegebenen Account zurückzuliefern, sofern alles erfolgreich war. +-- +-- Können sie beide Varianten (einmal mittels `do`-notation und einmal mit +-- `>>=`) schreiben? diff --git a/Übungen/Blatt3.lhs b/Übungen/Blatt3.lhs new file mode 100644 index 0000000..6448e12 --- /dev/null +++ b/Übungen/Blatt3.lhs @@ -0,0 +1,113 @@ +Übungsblatt 3 +============= + +Throat-Clearing +--------------- + +a.k.a. Imports, damit der Code funktioniert. + +> module MonadExercise where +> import Control.Applicative +> import Control.Monad +> import Data.Monoid + +Vorwort +------- + +Die Typklassen, die auf diesem Zettel implementiert werden sollen sind +teilweise nicht eindeutig. Ein gutes *Indiz* für eine falsche +implementation kann sein, dass Informationen "weggeschmissen" werden - +allerdings muss man bei anderen Implementationen genau dies machen. + +Applicative +----------- + +Nachdem wir uns letzte Woche ausführlich mit der Typklasse `Functor` +beschäftigt haben, bauen wir nun darauf auf und definieren die +Applicative-Instanz. Zur Erinnerung: + + class Functor f => Applicative f where + pure :: a -> f a + <*> :: f (a -> b) -> f a -> f b + +Nehmen sie an, sie hätten folgende Datentypen mit ihren +`Functor`-Instanzen gegeben. Schreiben sie jeweils die +Applicative-Instanz: + +> data Identity a = Identity { unIdentity :: a } +> deriving (Show, Eq) +> +> instance Functor Identity where +> fmap f (Identity a) = Identity (f a) +> +> data Vielleicht a = Etwas a +> | Nichts +> deriving (Show, Eq) +> +> instance Functor Vielleicht where +> fmap f (Etwas a) = Etwas (f a) +> fmap _ Nichts = Nichts +> +> data EntwederOder b a = Entweder a +> | Oder b +> deriving (Show, Eq) +> +> instance Functor (EntwederOder b) where +> fmap f (Entweder a) = Entweder (f a) +> fmap _ (Oder b) = Oder b +> +> data List a = Cons a (List a) +> | Nil +> deriving (Show, Eq) +> +> instance Functor List where +> fmap f (Cons a r) = Cons (f a) (fmap f r) +> fmap _ Nil = Nil +> +> instance Monoid (List a) where +> mempty = Nil +> mappend Nil bs = bs +> mappend (Cons a as) bs = Cons a (mappend as bs) +> +> data V3 a = V3 a a a +> +> instance Functor V3 where +> fmap f (V3 x y z) = V3 (f x) (f y) (f z) + +Monad +----- + +Zu welchen der oben aufgeführten Typen gibt es eine Monaden-Instanz? Wie +sieht diese aus? Schreiben sie diese (falls möglich). + +Bonus +----- + +> data Account = Account +> data Inbox = Inbox +> data Mail = Mail + +Seien folgende Funktionen gegeben: + +> login :: Maybe Account +> login = undefined +> +> getInbox :: Account -> Maybe Inbox +> getInbox = undefined +> +> getMails :: Inbox -> [Mail] +> getMails = undefined +> +> safeHead :: [a] -> Maybe a +> safeHead = undefined + +Schreiben sie eine Funktion: + +> getFirstMail :: Maybe Mail +> getFirstMail = undefined + +welche die oben genannten 4 Funktionen nutzt um die erste Mail aus dem +gegebenen Account zurückzuliefern, sofern alles erfolgreich war. + +Können sie beide Varianten (einmal mittels `do`-notation und einmal mit +`>>=`) schreiben? diff --git a/Übungen/Blatt3.md b/Übungen/Blatt3.md new file mode 100644 index 0000000..7423b69 --- /dev/null +++ b/Übungen/Blatt3.md @@ -0,0 +1,101 @@ +# Übungsblatt 3 + +## Throat-Clearing + +a.k.a. Imports, damit der Code funktioniert. + +```haskell +import Control.Applicative +import Control.Monad +import Data.Monoid +``` + +## Vorwort + +Die Typklassen, die auf diesem Zettel implementiert werden sollen sind teilweise nicht eindeutig. Ein gutes *Indiz* für eine falsche implementation kann sein, dass Informationen "weggeschmissen" werden - allerdings muss man bei anderen Implementationen genau dies machen. + +## Applicative + +Nachdem wir uns letzte Woche ausführlich mit der Typklasse `Functor` beschäftigt haben, bauen wir nun darauf auf und definieren die Applicative-Instanz. +Zur Erinnerung: + + class Functor f => Applicative f where + pure :: a -> f a + <*> :: f (a -> b) -> f a -> f b + +Nehmen sie an, sie hätten folgende Datentypen mit ihren `Functor`-Instanzen gegeben. Schreiben sie jeweils die Applicative-Instanz: + +```haskell +data Identity a = Identity { unIdentity :: a } + deriving (Show, Eq) + +instance Functor Identity where + fmap f (Identity a) = Identity (f a) + +data Vielleicht a = Etwas a + | Nichts + deriving (Show, Eq) + +instance Functor Vielleicht where + fmap f (Etwas a) = Etwas (f a) + fmap _ Nichts = Nichts + +data EntwederOder b a = Entweder a + | Oder b + deriving (Show, Eq) + +instance Functor (EntwederOder b) where + fmap f (Entweder a) = Entweder (f a) + fmap _ (Oder b) = Oder b + +data List a = Cons a (List a) + | Nil + deriving (Show, Eq) + +instance Functor List where + fmap f (Cons a r) = Cons (f a) (fmap f r) + fmap _ Nil = Nil + +instance Monoid List where + mempty = Nil + mappend Nil bs = bs + mappend (Cons a as) bs = Cons a (mappend as bs) + +data V3 a = V3 a a a + +instance Functor V3 where + fmap f (V3 x y z) = V3 (f x) (f y) (f z) +``` + +## Monad + +Zu welchen der oben aufgeführten Typen gibt es eine Monaden-Instanz? Wie sieht diese aus? Schreiben sie diese (falls möglich). + + +## Bonus + +Seien folgende Funktionen gegeben: + +```haskell +login :: Maybe Account +login = undefined + +getInbox :: Account -> Maybe Inbox +getInbox = undefined + +getMails :: Inbox -> [Mail] +getMails = undefined + +safeHead :: [a] -> Maybe a +safeHead = undefined +``` + +Schreiben sie eine Funktion: + +```haskell +getFirstMail :: Maybe Mail +``` + +welche die oben genannten 4 Funktionen nutzt um die erste Mail aus dem gegebenen Account zurückzuliefern, sofern alles erfolgreich war. + +Können sie beide Varianten (einmal mittels `do`-notation und einmal mit `>>=`) schreiben? diff --git a/Übungen/Blatt3.pdf b/Übungen/Blatt3.pdf new file mode 100644 index 0000000..c846319 Binary files /dev/null and b/Übungen/Blatt3.pdf differ