Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.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
Macros 在Clojure中,什么时候应该使用单子而不是宏,反之亦然?_Macros_Clojure_Monads - Fatal编程技术网

Macros 在Clojure中,什么时候应该使用单子而不是宏,反之亦然?

Macros 在Clojure中,什么时候应该使用单子而不是宏,反之亦然?,macros,clojure,monads,Macros,Clojure,Monads,有太多关于单子的教程说。。。“看!这是一个我们可以使用单子的例子”或“这就是单子的用途”。我想知道的是,人们通过哪些步骤得出结论,他们可以对自己说:“天哪!看起来我们可以在这里使用单子!” 所以当有人告诉我。。。“(诸如此类)与单子无关……”,它真的不能帮助我回答我的问题,这些问题是: 我如何确定程序中的哪种模式可以用单子表示 当我确定了使用单子的可能性时,我如何编写自己的定制单子 我在这里开始了一个很长的问题,关于monads,如果有人有兴趣帮忙- 回到这个问题: 我们什么时候应该使用单子

有太多关于单子的教程说。。。“看!这是一个我们可以使用单子的例子”或“这就是单子的用途”。我想知道的是,人们通过哪些步骤得出结论,他们可以对自己说:“天哪!看起来我们可以在这里使用单子!”

所以当有人告诉我。。。“(诸如此类)与单子无关……”,它真的不能帮助我回答我的问题,这些问题是:

  • 我如何确定程序中的哪种模式可以用单子表示
  • 当我确定了使用单子的可能性时,我如何编写自己的定制单子
我在这里开始了一个很长的问题,关于monads,如果有人有兴趣帮忙-

回到这个问题:

我们什么时候应该使用单子而不是宏,反之亦然

  • 我读过一些文章,也看过一些演讲,上面写着单子用于DSL抽象“。。。。但是大多数Clojure DSL库(如hiccup和korma)都使用了
    defmacro
    ,而且效果很好

如果我们有宏,为什么我们需要Clojure中的monads?

我已经使用Clojure两年了,我唯一一次使用monads是为了证明它是可以实现的。我从来都不需要它们来编写真正的代码

单子在Haskell中更为常见,因为:

  • 它们是处理有状态计算的惯用方法。在Clojure中,您通常使用处理状态,因此Clojure中几乎不需要使用单子
  • 同样,对于IO:Clojure允许您直接执行IO,而无需在类型中声明,因此您不需要IO monad
我的建议是专注于Clojure中的标准函数式编程。除非你看到你真的需要单子,否则我不会花太多时间把它们带进来

宏是一个稍微不同的问题:它们用于编译时代码生成和语言语法的扩展(可能包括DSL,尽管DSL不一定需要宏)。当以下两项均为真时,我使用宏:

  • 我想以一种显著提高我解决特定问题领域能力的方式扩展语言语法
  • 我无法获得与普通函数/函数组合相同的功能。如果可能的话,普通函数应该是您的首选:它们通常更易于编写和维护
  • 另外,如果你真的对Clojure的monads感兴趣,这里有两个我个人觉得很好的视频:

    • (布莱恩·马里克对单子的出色视觉解释)

    单子和宏没有任何共同之处。它们用于解决不同的问题。在Clojure中,monad库非常广泛地使用宏来实现monad的语法“用户界面”。您可以使用monad实现一些库的功能,而不是为外部接口添加一层宏

    至于“何时在Clojure中使用Monad”,我看到了两个用例:

    1) 为了完成任务,在多个monad中实现有意义的东西 只有一次,然后“插入”单子。这是一个很好的例子 尽管不幸的是(从教育学的角度来看)对于 非平凡应用:逻辑编程

    2) 实现一种合成技术,这种合成技术可以用单子表示,以便 从现有monad基础设施中获利

    Clojure有两个内置单子,“let”(身份单子)和“for”(序列单子)。当您希望以后可以将其中一个插入到代码中时,应该使用“domonad”。当你希望你有相似但不完全相同的时候,你应该考虑写你自己的单子。
    不幸的是,这仍然相当抽象。目前,在Clojure中使用Monad的已发布和完善的代码示例并不多。随着越来越多的Clojuris人熟悉monad,越来越多的monad专家(通常来自Haskell)使用Clojure,这种情况可能会改变。例如,我在Clojure中看到过(但手头没有)一元语法分析。

    @khinsen和@mikera很好地回答了这个问题,很难再作任何评论,但我认为他们遗漏了一点(或者我在他们的评论中找不到)

    在Clojure中,宏是语言的一部分。使用与否,但它们就在那里。事实上,您通常别无选择,只能使用它们,因为它们使您的应用程序更加地道(这是专业使用任何语言的一个特点)。它们允许您预处理组成应用程序的数据结构。它们与其他语言结构类似,因为它们与您的需求无关

    与宏不同,单子不是Clojure的一部分。它们是使用语言的结构(即宏)构建的。除非您坚持要在运行时包含它们,否则它们不会在运行时包含。对我来说,monad是用于组合计算的设计模式,因此它们类似于您可能熟悉的其他设计模式。您使用设计模式来开发模块化和内聚的应用程序,无论是单子、宏还是任何其他语言结构,您都应该知道它们的存在,并为您的利益使用它们

    至于你的问题,宏在单子出现之前就开始工作了。宏在编译阶段工作-它们将数据结构更改为其他数据结构。monad是一种用于组合计算的设计模式。这就是区别。在Clojure中,monad是使用宏编写的(以便更容易使用),因此人们倾向于说可以使用宏轻松实现的monad。Clojure中的Monad设计的确如此,但宏本身也可能如此。大多数时候你不需要写新的,