繁体   English   中英

初体验Monads(Haskell)

[英]First experience with monads (Haskell)

对于这个主题不清楚,我深表歉意。 我正在初学者学习Haskell 99,并且在我的67A解决方案中第一次遇到了monad的概念。 我苦苦挣扎的问题的一部分是定义一个函数stringToTree ,该函数将a(b,c)a(b,c)序列转换为TreeBranch a (Branch b Empty Empty) (Branch c Empty Empty)

我已经尝试了几种有关monad的“软”介绍,但与其他许多例子一样都失败了。 我希望通过了解此解决方案最终能带领我进入室内,因此我决定在此进行尝试。

问题

  1. 谁能简要解释一下解决方案中定义的函数stringToTree :: (Monad m) => String -> m (Tree Char)是什么? 为了使这个问题自成一体,我从那里复制了代码
stringToTree :: (Monad m) => String -> m (Tree Char)
stringToTree "" = return Empty
stringToTree [x] = return $ Branch x Empty Empty
stringToTree str = tfs str >>= \ ("", t) -> return t
    where tfs a@(x:xs) | x == ',' || x == ')' = return (a, Empty)
          tfs (x:y:xs)
                | y == ',' || y == ')' = return (y:xs, Branch x Empty Empty)
                | y == '(' = do (',':xs', l) <- tfs xs
                                (')':xs'', r) <- tfs xs'
                                return $ (xs'', Branch x l r)
          tfs _ = fail "bad parse"
  1. 为什么monad在这里有用? 我希望看到单子如何在定义此功能的同时大幅度减少困难,当然只有在了解了这一点之后。

简而言之,定义使呼叫者可以选择要使用的单声道。 这使我们可以自定义处理失败的方式。 例如,我们可以使用Maybe

>>> stringToTree "" :: Maybe (Tree Char)
Just Empty
>>> stringToTree "9 +" :: Maybe (Tree Char)
Nothing

[]

>>> stringToTree "" :: [Tree Char]
[Empty]
>>> stringToTree "9 +" :: [Tree Char]
[]

该代码本身不假设使用哪个 monad。 它仅使用>>=return ,并且fail处理递归调用的结果。

键入String -> Tree Char表示失败根本不会发生。 每个字符串都必须产生一个有效的Tree Char值(否则我们会引发运行时错误,这是您在Haskell中应避免的事情)。

但是请注意,并非所有monad都提供了避免运行时错误的fail定义。

>>> stringToTree "" :: Either () (Tree Char)
Right Empty
>>> stringToTree "9 +" :: Either () (Tree Char)
*** Exception: bad parse

为什么monad有用? 一些更广泛的背景。

Monad是传统上由不同语言机制处理的几件事的统一 其中有

  • 排序(例如在IO或状态下)

  • 非确定性(例如清单monad)

  • 失败和异常(例如Maybe)

  • 保存和恢复计算(将来会遇到的Cont monad)

  • 原子交易(STM monad)

  • 解析(Parsec及其亲属)

所谓“统一”,是指牛顿将地球上和天空中的事物的物理定律统一起来,或者将麦克斯韦将电磁力统一到电磁场中时所做的事情。 它是一种更深层的基础理论,将以上所有内容作为特殊情况进行了介绍,并展示了如何沿着相同思路创造新事物。

在monad中,“ bind”函数的类型(>>=)是理论中的中心方程; 它描述了如何将计算的一个步骤以菊花链方式链接到下一个步骤。 return是原始的空步骤。 这是您在Haskell中习惯的; 一切都有某种零或空或身份值。 fail是不起作用的步骤,部分功能需要该步骤(如@chepner在其他评论中所述)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM