Skip to content

Instantly share code, notes, and snippets.

@lin1987www
Created October 17, 2018 15:23
Show Gist options
  • Save lin1987www/41ea83060cb6879c4547ec4562d482f5 to your computer and use it in GitHub Desktop.
Save lin1987www/41ea83060cb6879c4547ec4562d482f5 to your computer and use it in GitHub Desktop.
Haskell - The Writer type
{-
learnyouahaskell.com/for-a-few-monads-more#writer
-}
newtype Writer2 w a = Writer2 { runWriter2 :: (a, w) } deriving (Eq, Show)
instance Functor (Writer2 w) where
fmap f m = let
(a, w) = (runWriter2 m)
in Writer2 (f a, w)
{-
http://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Functor.html#t:Functor
class Functor f where
fmap :: (a -> b) -> f a -> f b
Functor 至少要實作 fmap
> fmap (+1) (Writer2 (0,"Hi"))
Writer2 {runWriter2 = (1,"Hi")}
-}
instance (Monoid w) => Applicative (Writer2 w) where
pure a = Writer2 (a, mempty)
f <*> v = let
(a, w) = (runWriter2 f)
(b, w') = (runWriter2 v)
in Writer2 (a b, w `mappend` w')
{-
http://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Applicative.html#t:Applicative
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
Applicative至少要實作 pure, ((<*>) 或是 liftA2)
根據 Applicative 的定義 還需要實作 Functor
> (Writer2 ((+1),"plus one to ")) <*> (Writer2 (0,"zero"))
Writer2 {runWriter2 = (1,"plus one to zero")}
-}
instance (Monoid w) => Monad (Writer2 w) where
return a = Writer2 (a, mempty)
m >>= f = let
(a, w) = runWriter2 m
(b, w') = runWriter2 (f a)
in Writer2 (b, w `mappend` w')
{-
http://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Monad.html#t:Monad
class Applicative m => Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
Monad 至少要實作 (>>=)
因此 若想實作 Monad (Writer2 w) 就必須同時實作其所倚賴的 Applicative
> (Writer2 (0, "zero")) >>= (\ x-> Writer2 (x+1," ," ++ show x ++ "+1=" ++ show (x+1)))
Writer2 {runWriter2 = (1,"zero ,0+1=1")}
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment