Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell MaybeT的这种特殊用法是如何工作的?_Haskell - Fatal编程技术网

Haskell MaybeT的这种特殊用法是如何工作的?

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)

我正在努力学习monad transformers,我正在阅读haskell维基上的文章

我感到困惑的代码如下:

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