I am trying to nest writer monad twice using Monad Transformers. Here is a sketch:
import Control.Monad.Identity
import Control.Monad.Writer
data Struct = S Bool
instance Monoid Struct where
mempty = S True
mappend (S a) (S b) = S (a && b)
data Collision = C Bool
instance Monoid Collision where
mempty = C False
mappend (C a) (C b) = C (a || b)
type CSInt = WriterT Collision (WriterT Struct Identity) Int
foo :: Int -> CSInt
foo x = do (tell (S False)) ; return x
The foo
function does not compile, as I need to use tell
on Struct
monad, not Collision
. Is it possible at all?
Having multiple similar layers is in fact one case where the
mtl
approach, which is meant to makelift
implicit, has trouble as you mentionned. So you can uselift
explicitly.Thus