monad上有太多的教程说......“看!这是我们可以使用monad的情况”或“这就是monad的用途”。我想知道的是,人们用什么步骤得出他们可以对自己说的结论 - “Gee Whiz!看起来我们可以在这里使用monad!”
所以,当有人告诉我......“(等等)与monad无关......”,它真的无法帮助我回答我的问题:
如果有人有兴趣帮助我,我在这里开始了一个关于monads的非常长的问题 - Map and Reduce Monad for Clojure... What about a Juxt Monad?。
回到这个问题:
我们什么时候应该使用monad而不是宏?反之亦然?
如果我们有宏,为什么我们需要在clojure中使用monad?
答案 0 :(得分:36)
我现在已经使用Clojure两年了,而且我唯一一次使用monad作为练习来证明它可以完成。我从来没有将它们用于“真正的”代码。
Monads在Haskell中更常见,因为:
我的建议是专注于Clojure中的标准函数式编程。除非你看到你真的需要 monad,否则我不会投入太多时间试图引入它们。
宏是一个稍微不同的问题:它们用于编译时代码生成和语言语法的扩展(可能包括DSL,尽管DSL不一定需要宏)。当满足以下两个条件时,我使用宏:
P.S。如果你真的对Clojure的monads感兴趣,这里有两个我个人觉得非常好的视频:
答案 1 :(得分:16)
Monads和宏没有任何共同之处。它们用于解决不同的问题。在Clojure中,monad库非常广泛地使用宏来实现monad的语法“用户界面”。您可以使用monads在功能上实现某些库,而不是为外部接口添加一层宏。
至于“何时会在Clojure中使用monad”,我会看到两个用例:
1)为了完成这项工作,要在多个monad中实现有意义的东西 只有一次,然后“插入”monad。 Here就是一个很好的例子 虽然不幸(从教学的角度来看)是一种相当的方法 非平凡的应用:逻辑编程。
2)为了实现可以表述为monad的合成技术 从现有的monad基础设施中获利。
Clojure有两个内置monad,“let”(身份monad)和“for”(序列monad)。只要您希望以后可以将其中一个插入到代码中,就应该使用“domonad”。无论何时你希望你有类似但不完全相同的东西,你应该考虑编写自己的monad。
遗憾的是,这仍然相当抽象。目前在Clojure中使用monad的发布和抛光代码示例并不多。随着越来越多的Clojurians熟悉monad和更多Monad专家(通常来自Haskell)使用Clojure,这可能会改变。例如,我在Clojure中看过(但没有手头)monadic解析。
答案 2 :(得分:4)
@khinsen和@mikera很好地回答了这个问题,但很难再做出任何补充评论,我认为他们错过了一点(或者我在评论中找不到它)。
在Clojure中,宏是语言的一部分。是否使用它们,但它们在那里。事实上,你经常别无选择,只能使用它们,因为它们使你的应用程序更加惯用(这是专业使用任何语言的一个特征)。它们允许您预处理构成应用程序的数据结构。它们与其他语言结构类似,无论您的需求如何,它们都被包含在内。
与宏不同,monad不是Clojure的一部分。它们是使用语言的结构构建的,即宏。它们不会包含在运行时,除非您坚持要求它们存在。对我来说monad是用于组合计算的设计模式,因此它们类似于您可能熟悉的其他设计模式。您可以使用设计模式来开发模块化和有凝聚力的应用程序,无论是monad还是宏,还是您应该知道它们存在的任何其他语言构造,并为您的利益与它们合作。
关于你的问题,宏在monad进入之前工作。宏在编译阶段工作 - 他们将数据结构更改为其他数据结构。 Monads是一种组合计算的设计模式。这就是区别。在Clojure中,monad是使用宏编写的(为了使它们的使用更容易),因此人们倾向于说你可以用宏来轻松实现的monad。这是真的,因为它来自Clojure中的monads设计,但对于宏本身也可以这么说。你不需要在大多数时候写新的,the first rule of the macro club is to not write them,但他们仍然是语言的一部分,你应该非常了解他们的应用程序。
有关宏的更多讨论,请参阅How do Clojure programmers use Macros?。