Haskell 梅贝特的直觉
我试图通过在Haskell 梅贝特的直觉,haskell,monad-transformers,Haskell,Monad Transformers,我试图通过在ghci中运行几个示例来理解MaybeT: λ: import Control.Monad.Trans.Maybe λ: let x = return $ 42 :: MaybeT (Either String) Int λ: :t x x :: MaybeT (Either String) Int 然后,我运行它: λ: runMaybeT x Right (Just 42) 请给我一个值,y,这样 runMaybeT y === Left (Just "...") runMa
ghci
中运行几个示例来理解MaybeT
:
λ: import Control.Monad.Trans.Maybe
λ: let x = return $ 42 :: MaybeT (Either String) Int
λ: :t x
x :: MaybeT (Either String) Int
然后,我运行它:
λ: runMaybeT x
Right (Just 42)
请给我一个值,y
,这样
runMaybeT y === Left (Just "...")
runMaybeT y === Left Nothing
runMaybeT y === Right Nothing
你永远不会得到一个
左无
或左(只是..)
,因为这里的单子是字符串…
,所以在左边你总是有一个字符串
以下是您可以获得的信息:
> let y = fail "Failed" :: MaybeT (Either String) Int
> runMaybeT y
Right Nothing
> let y = lift (Left "Failed") :: MaybeT (Either String) Int
> runMaybeT y
Left "Failed"
这可能有助于通过MaybeT了解引擎盖下面的情况 在IO单子中,我们有计算,例如
putStrLn "Hello, world!" :: IO ()
getContents :: IO String
等等。所有这些计算都有类型IO a
,实际上类型变量a
是不受限制的-它可以是任何类型。使用return
我们可以为任何类型的a
创建IO计算IO a
您可以将MaybeT IO
看作是返回一个Maybe值的IO计算。
例如,getContents
是一个IO
计算,但不是MaybeT IO
计算。但是,有一种明显的方法可以将getContents
转换为MaybeT IO
计算——只需将其输出包装在Just
构造函数中:
lift getContents === fmap Just getContents
lift
是将IO
计算提升为MaybeT IO
计算的方法。将此应用于return\u IO
(用于IO
monad的return
函数),我们有:
也就是说,return 3
(在MaybeT IO
monad中)与IO
monad中的return(仅3)
相同
runMaybeT和MaybeT是彼此相反的
现在看一看
这也描述了MaybeT m
中的计算与m
中返回Maybe值的计算相同的思想。职能:
MaybeT :: m (Maybe a) -> MaybeT m a
runMaybeT :: MaybeT m a -> m (Maybe a)
都是相反的,除了添加或删除newtype包装器之外,什么都不做。对于IO
monad:
MaybeT :: IO (Maybe a) -> MaybeT IO a
runMaybeT :: MaybeT IO a -> IO (Maybe a)
考虑到您问题中的示例,我们看到,MaybeT(任一字符串)
中的计算基本上与任何类型a
的类型任一字符串(可能是a)
的值相同。这导致了以下可能性:
- 某个字符串的左
对(只是…
Right Nothing
任一字符串(可能是a)
中,如果我们将构造函数MaybeT
应用于它们中的每一个,我们将在MaybeT(可能是a)
中得到相应的值
特别是,要查找y
s.t
runMaybeT y == Right Nothing
只需使用:
y = MaybeT (Right Nothing)
同样,runMaybeT
和MaybeT
是彼此相反的,因此您可以通过将MaybeT
应用到两侧来获得相同的结果
runMaybeT y == Right Nothing
y = MaybeT (Right Nothing)