进入包裹在变压器中的单子
Getting inside a monad wrapped in transformer
这是一个使用 Reader 转换器的人为示例:
{-# 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。可以做吗,还是我有"design issues"?
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
,它是一个读取环境和returns Maybe a
的函数。您可以创建一个读取环境并检查结果是否为 Nothing
的函数,方法是将此函数与另一个检查结果是否为 Nothing
的函数组合。要检查 Maybe a
是否为空,我们可以使用 isJust
,并将结果 Bool
打包回 Maybe Bool
我们将使用 return
.
inspect :: ReaderT r Maybe a -> ReaderT r Maybe Bool
inspect (ReaderT f) = ReaderT $ return . isJust . f
transformers 提供了一个函数,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)
这是一个使用 Reader 转换器的人为示例:
{-# 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。可以做吗,还是我有"design issues"?
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
,它是一个读取环境和returns Maybe a
的函数。您可以创建一个读取环境并检查结果是否为 Nothing
的函数,方法是将此函数与另一个检查结果是否为 Nothing
的函数组合。要检查 Maybe a
是否为空,我们可以使用 isJust
,并将结果 Bool
打包回 Maybe Bool
我们将使用 return
.
inspect :: ReaderT r Maybe a -> ReaderT r Maybe Bool
inspect (ReaderT f) = ReaderT $ return . isJust . f
transformers 提供了一个函数,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)