I was writing my code with Control.Monad.Writer.Lazy using (,) [String] as my writer monad. But I found that (>>=) and (>>) are too strict with the monoid operator? They cause infinte loop with this code for example:
type Wrtr a = ([String], a)
writer (x, w) = (w, x)
main :: IO ()
main = do
let one = writer ((), ["goodbye"])
let w = foldr1 (>>) $ repeat one
let (log, _) = w
mapM_ putStrLn . take 5 $ log
This code will loop endlessly and never print anything and it's bad for me. So for now I'm using this naive implementation of the same monad, which seems to be fine and lazy:
data Writer w a = Writer w a
instance Functor (Writer w) where
fmap f (Writer w x) = Writer w (f x)
instance Monoid w => Applicative (Writer w) where
pure x = Writer mempty x
(Writer w1 f) <*> (Writer w2 x) = Writer (w1 <> w2) (f x)
instance Monoid w => Monad (Writer w) where
return = pure
(Writer w1 x) >>= f =
let (Writer w2 y) = f x
in Writer (w1 <> w2) y
writer (x, w) = Writer w x
(You have to define functor and applicative instances because of monoid constraint)
If you then run the code with the same exact main function as above, it will print "goodbye" five times and exit.
So the question is: why are tuples so strict? Or if it's not strictness, what is it and why is it there?
BTW I'm using ghc 8.6.4 and everything else whihch comes with stack lts-13.19
(,) [String]monad, you are not usingControl.Monad.Writer.Lazy. I guess thebasemonad(,) [String]is isomorphic toControl.Monad.Writer.Strict.Writer [String]instead, which should loop on your code (once adapted). - chiWriteritself. Time to test it out. - MorJ