Haskell MaybeT的这种特殊用法是如何工作的?
我正在努力学习monad transformers,我正在阅读haskell维基上的文章 我感到困惑的代码如下:Haskell MaybeT的这种特殊用法是如何工作的?,haskell,Haskell,我正在努力学习monad transformers,我正在阅读haskell维基上的文章 我感到困惑的代码如下: isValid :: String -> Bool isValid s = length s >= 5 getValidPassword :: MaybeT IO String getValidPassword = do s <- lift getLine guard (isValid s)
isValid :: String -> Bool
isValid s = length s >= 5
getValidPassword :: MaybeT IO String
getValidPassword = do s <- lift getLine
guard (isValid s)
return s
askPassword :: MaybeT IO ()
askPassword = do lift $ putStrLn "Insert your new password:"
value <- getValidPassword
lift $ putStrLn "Storing in database..."
如果不满足有效性条件,这将重复等待我给出新的输入。我有点不明白它是怎么做到的repeat
将永远重复该操作,msum
只是foldr mplus mzero
,这意味着它将沿着列表移动并将值“相加”
为什么不在我输入错误时立即返回(返回值将为Nothing)。我想我没有看到决定何时停止和何时继续的逻辑被嵌入到哪里。谢谢你的帮助 好的,
msum
for也许应该在第一次成功尝试时停止,而不是第一次失败。这是有效的,因为MaybeT的mplus在其第二个参数中是不严格的:
mplus (return () :: MaybeT m ()) undefined
相当于
return ()
这是一个结果,如下所示:
instance (Monad m) => MonadPlus (MaybeT m) where
mzero = MaybeT (return Nothing)
mplus x y = MaybeT $ do v <- runMaybeT x
case v of
Nothing -> runMaybeT y
Just _ -> return v
instance(Monad m)=>MonadPlus(MaybeT m)其中
mzero=MaybeT(不返回任何内容)
mplus x y=MaybeT$do v runMaybeT y
只需返回v
如您所见,除非第一个参数x
未能返回结果,否则不会执行mplus的第二个参数y
因此,从repeat getPassword
获得的无限操作列表中的msum
将仅在第一个操作成功之前执行
instance (Monad m) => MonadPlus (MaybeT m) where
mzero = MaybeT (return Nothing)
mplus x y = MaybeT $ do v <- runMaybeT x
case v of
Nothing -> runMaybeT y
Just _ -> return v