{- 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")} -}