进入变压器包裹的monad

时间:2015-10-31 16:06:11

标签: haskell monads monad-transformers

这是使用Reader Transformer的一个有用的例子:

{-# LANGUAGE UnicodeSyntax #-}

import Control.Monad.Reader
import Data.Char

conv ∷ Int → ReaderT Char Maybe String
conv n = do
   yn ← ask
   if yn == 'y'
      then return $ chr n : " with Yes"
      else lift Nothing

-- runReaderT (conv 98) 'y'      Just "b with Yes"
-- runReaderT (conv 98) '@'      Nothing

inspect ∷ ReaderT Char Maybe String → Bool

- 编辑:根据建议,正确的类型是monadic:

inspect ∷ ReaderT Char Maybe String → ReaderT Char Maybe Bool

inspect应该检查里面的值是否为Nothing。可以这样做,还是我有“设计问题”?

1 个答案:

答案 0 :(得分:2)

ReaderT正是

newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
        -- a function that reads the environment^    |
        --                         and returns an m a^

对于ReaderT r Maybe a,它是一个读取环境并返回Maybe a的函数。您可以通过将此函数与另一个检查结果是Nothing的函数组合来创建一个读取环境并检查结果是否为Nothing的函数。要检查Maybe a是否一无所知,我们可以使用isJust,并将生成的Bool打包回Maybe Bool,我们会使用return。< / p>

inspect :: ReaderT r Maybe a -> ReaderT r Maybe Bool
inspect (ReaderT f) = ReaderT $ return . isJust . f

变形金刚提供了一个函数mapReaderT,让我们可以操纵ReaderT

中的计算
mapReaderT :: (m a -> n b) -> ReaderT r m a -> ReaderT r n b
mapReaderT f m = ReaderT $ f . runReaderT m

mapReaderT只是将ReaderT中的函数作为第一个参数提供的函数组成(runReaderT展开ReaderT内的函数)。您可以使用mapReaderT更优雅地编写inspect

inspect :: ReaderT r Maybe a -> ReaderT r Maybe Bool
inspect = mapReaderT (return . isJust)