gpt4 book ai didi

haskell - Parsec:应用程序与 Monads

转载 作者:行者123 更新时间:2023-12-03 11:44:02 25 4
gpt4 key购买 nike

我刚开始使用 Parsec(在 Haskell 方面经验很少),我对使用 monads 或 applicatives 有点困惑。阅读“Real World Haskell”、“Write You a Haskell”后,我的总体感觉是应用程序是首选,但我真的不知道。

所以我的问题是:

  • 首选什么方法?
  • monads 和 applicatives 可以混合使用吗(当它们比另一个更有用时使用它们)
  • 如果最后一个答案是肯定的,我应该这样做吗?
  • 最佳答案

    可能值得关注 Applicative 之间的关键语义差异。和 Monad , 以确定何时适合。比较类型:

    (<*>) :: m (s -> t) -> m s -> m t
    (>>=) :: m s -> (s -> m t) -> m t

    部署 <*> ,您选择两种计算,一种是函数,另一种是参数,然后它们的值由应用程序组合。部署 >>= ,你选择一个计算,并解释你将如何利用它的结果值来选择下一个计算。这是“批处理模式”和“交互”操作的区别。

    在解析方面, Applicative (扩展失败并选择给出 Alternative )捕获语法的上下文无关方面。您将需要 Monad 的额外力量仅当您需要从输入的一部分检查解析树以决定应将哪种语法用于输入的另一部分时才为您提供。例如,您可能会读取格式描述符,然后读取该格式的输入。尽量减少对 monad 额外功能的使用会告诉您哪些值依赖是必不可少的。

    从解析转向并行,这个使用 >>= 的想法只有基本的值(value)依赖才能让您清楚地了解分散负载的机会。当两个计算与 <*> 结合时,两者都不需要等待另一个。 Applicative-when-you-can-but-monadic-when-you-must 是速度的公式。 ApplicativeDo的点是自动对以单子(monad)样式编写的代码进行依赖性分析,从而意外地过度序列化。

    您的问题还与编码风格有关,关于哪些意见可以自由不同。但是让我告诉你一个故事。我从标准 ML 来到 Haskell,在那里我习惯于直接编写程序,即使它们做了一些淘气的事情,比如抛出异常或变异引用。我在 ML 中做什么?致力于实现超纯类型理论(出于法律原因,可能未命名)。在使用那种类型理论时,我无法编写使用异常的直接式程序,但我将应用组合器作为一种尽可能接近直接式的方法。

    当我搬到 Haskell 时,我震惊地发现人们似乎认为伪命令式 do-notation 编程只是对最轻微的语义杂质的惩罚(当然,除了不终止)。早在我掌握语义区别之前,我就采用了应用组合符作为样式选择(甚至更接近于使用“成语方括号”的直接样式),即它们代表了对 monad 接口(interface)的有用弱化。我只是不(现在仍然不)喜欢 do-notation 需要表达结构碎片化和无端命名事物的方式。

    也就是说,使函数式代码比命令式代码更紧凑和可读的相同事物也使应用程序样式比 do-notation 更紧凑和可读。我很感激 ApplicativeDo是一种让您没有时间重构的以单子(monad)风格编写的程序更具应用性(在某些情况下意味着更快)的好方法。但除此之外,我认为 applicative-when-you-can-but-monadic-when-you-must 也是了解正在发生的事情的更好方法。

    关于haskell - Parsec:应用程序与 Monads,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38707813/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com