Writer Monad

Run Settings
LanguageHaskell
Language Version
Run Command
module Main where import Data.Monoid import Control.Monad ((>=>)) data Writer w a = Writer a w runWriter :: Writer w a -> (a, w) runWriter (Writer a w) = (a, w) tell :: w -> Writer w () tell s = Writer () s instance (Monoid w) => Functor (Writer w) where -- fmap :: (a -> b) -> Writer w a -> Writer w b fmap f (Writer a w) = Writer (f a) w instance (Monoid w) => Applicative (Writer w) where -- pure :: a -> Writer w a pure x = Writer x mempty -- (<*>) :: Writer w (a -> b) -> Writer w a -> Writer w b (Writer f m1) <*> (Writer a m2) = Writer (f a) (m1 <> m2) instance (Monoid w) => Monad (Writer w) where -- (Writer w a) -> (a -> Writer w b) -> (Writer w b) (Writer a w) >>= k = let (b, w') = runWriter (k a) in Writer b (w <> w') -- Exemplo isEvenW x = (even x, " even ") notW b = (not b, " not ") isOddW x = let (b1, w1) = isEvenW x (b2, w2) = notW b1 in (b2, w1 <> w2) isEvenW' :: Integer -> Writer String Bool isEvenW' x = do tell " even " return (even x) notW' :: Bool -> Writer String Bool notW' b = do tell " not " return (not b) {- isOddW' x = do b1 <- isEvenW' x b2 <- notW' b1 return b2 -} isOddW' :: Integer -> Writer String Bool isOddW' = (isEvenW' >=> notW') -- outro exemplo fiboW :: Int -> Writer (Sum Int) Int fiboW 0 = do tell (Sum 1) return 0 fiboW 1 = do tell (Sum 1) return 1 fiboW n = do tell (Sum 1) f1 <- fiboW (n-1) f2 <- fiboW (n-2) return (f1+f2) main = do print $ runWriter $ isOddW' 3 mapM_ (print . runWriter . fiboW) [1..10]
Editor Settings
Theme
Key bindings
Full width
Lines