Haskell 进入一个包裹在变压器里的单子

Haskell 进入一个包裹在变压器里的单子,haskell,monads,monad-transformers,Haskell,Monads,Monad Transformers,这是一个使用读卡器转换器的设计示例: {-# 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 -- runRea

这是一个使用读卡器转换器的设计示例:

{-# 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
--编辑:根据建议,正确的类型为一元:

inspect ∷ ReaderT Char Maybe String → ReaderT Char Maybe Bool
inspect
用于检查内部的值是否为空。这是可以做到的,还是我有“设计问题”?

正是如此

newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
        -- a function that reads the environment^    |
        --                         and returns an m a^
对于
ReaderT r可能是一个
函数,它读取环境并返回一个
可能是一个
。通过将此函数与另一个检查结果是否为
Nothing
的函数组合,可以创建一个读取环境并检查结果是否为
Nothing
的函数。要检查a
可能a
是否为空,我们可以使用,并且要将得到的
Bool
打包回a
可能Bool
中,我们可以使用
return

inspect :: ReaderT r Maybe a -> ReaderT r Maybe Bool
inspect (ReaderT f) = ReaderT $ return . isJust . f
transformers提供了一个函数,允许我们在
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)

如果不运行读卡器,就无法检查值,因为答案取决于环境中的值。当然不是。Lee的意思是你想要
inspect::ReaderT Char Maybe String->ReaderT Char Maybe Bool
-你给出的签名基本上只能返回一个常量(它可以用自己的环境/
Char
等反馈
阅读器