Writer Monad

Sign in to test your solution.
import Control.Monad (ap, liftM) import Data.Monoid (Sum) newtype Writer w a = Writer { runWriter :: (a, w) } -- | Een logboek. type Log = [String] -- | Berekend fibonacci en toont welke berekeningen uitgevoerd werden in een log. -- Een lijst met als neutraal element [] en als operatie (++) is een monoïde. -- Vermijd het aanroepen van deze functie met grote getallen! fibonacciLog :: Int -> Writer Log Int fibonacciLog 0 = Writer (0, ["Recursiebasis 0."]) fibonacciLog 1 = Writer (1, ["Recursiebasis 1."]) fibonacciLog n = let (f1, l1) = runWriter $ fibonacciLog (n - 1) (f2, l2) = runWriter $ fibonacciLog (n - 2) in Writer (f1 + f2, l1 ++ l2 ++ ["Som van " ++ show f1 ++ " en " ++ show f2 ++ "."]) -- | Berekend fibonacci en telt hoe vaak we de recursiebasis bereiken. -- Een geheel getal met als operatie (+) en als neutraal element 0 is een monoïde. fibonacciCount :: Int -> Writer Int Int fibonacciCount 0 = Writer (0, 1) fibonacciCount 1 = Writer (1, 1) fibonacciCount n = let (f1, c1) = runWriter $ fibonacciCount (n - 1) (f2, c2) = runWriter $ fibonacciCount (n - 2) in Writer (f1 + f2, c1 + c2) -- | Een Writer is een instantie van Monad als de bijgehouden waarden een -- monoïde is. Op die manier kunnen we de verschillende bijgehouden waarden -- samenvoegen (`mappend`). instance (Monoid w) => Monad (Writer w) where return = undefined (>>=) = undefined instance (Monoid w) => Applicative (Writer w) where pure = undefined (<*>) = undefined instance (Monoid w) => Functor (Writer w) where fmap = undefined -- | Hulpfunctie voor het loggen van boodschappen. tell :: String -> Writer Log () tell message = undefined -- | Gelijk aan fibonacciLog, maar Monadisch geschreven (do of >>=) fibonacciLog' :: Int -> Writer Log Int fibonacciLog' = undefined -- Opmerking: gebruik hieronder "Sum Int" in plaats van "Int" waar je de monoïde -- nodig hebt: omdat gehele getallen een monoïde vormen met de som (neutraal -- element 0) maar ook met de vermenigvuldiging (neutraal element 1) moeten we -- aangeven welke monoïde we willen gebruiken. Daarvoor bestaan "newtype Sum" en -- "newtype Product". -- | Hulpfunctie om 1 te tellen. tick :: Writer (Sum Int) () tick = undefined -- | Gelijk aan fibonacciCount, maar Monadisch geschreven (do of >>=) fibonacciCount' :: Int -> Writer (Sum Int) Int fibonacciCount' = undefined
You can submit as many times as you like. Only your latest submission will be taken into account.
Sign in to test your solution.