Created
October 17, 2018 15:23
-
-
Save lin1987www/41ea83060cb6879c4547ec4562d482f5 to your computer and use it in GitHub Desktop.
Haskell - The Writer type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{- | |
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