How to apply a custom Monad Transformer

Say I have some Monadic type

data Example a = CheckIt {unwrap :: a}

instance Functor Example where
  fmap f (CheckIt x) = CheckIt (f x)

instance Applicative Example where
  pure = CheckIt
  CheckIt f <*> CheckIt x = CheckIt (f x)

instance Monad (Example) where
  return = CheckIt
  e@(CheckIt a) >>= f = f a

and I have a function which returns an [a] based on some input:

fetchList :: b -> [Int]
fetchList _ = [1,2,3,4]

and a function that returns an IO [a] (simplified from real implementation):

basicIoWrap :: [a] -> IO [a]
basicIoWrap x = return x

and I wish to run this IO and then extract an Example [a] from it:

The following does not work:

 foo :: b -> Example [a]
 foo val = (basicIoWrap (fetchList val)) >>= list -> return list

complaining about different monad types

 Couldn't match type ‘IO’ with ‘Example’
      Expected type: Example [a]
        Actual type: IO [Int]

So I understand that this is exactly the usecase for Monad transformers, but I am really struggling figuring out how to apply them in context. Say I had a transformer:

newtype ExampleT m a = ExampleT {runExampleT :: m (Example a)}

and I rephrased my signature to foo :: b -> ExampleT (IO [a])

I am unclear what the function body would then look like, and also, how I would eventually extract an Example [a] from this? Wouldn't runExampleT ExampleT (IO [a]) give an IO [Example a] , thus simply punting the multi Monad problem further down the road?


You can never safely "escape" from IO , but if you have a value of a type like Example (IO [a]) and Example is at least a Traversable , then you can turn it into IO (Example [a]) with the sequence function. Using this method you could write your foo function as:

foo :: b -> IO (Example [a])
foo = sequence . return . basicIoWrap . fetchList

Since you must already be working in the IO monad in order to use basicIoWrap , you can access the Example [a] . For example:

do input <- getLine
   (Example as) <- foo input
   mapM_ print as
链接地址: http://www.djcxy.com/p/77370.html

上一篇: Monad变形金刚电梯

下一篇: 如何应用自定义Monad Transformer