【问题标题】:What can be done with a Haskell monad that cannot be done with a Lisp macro, and vice-versa? [closed]用 Haskell monad 可以做什么,而 Lisp 宏不能做,反之亦然? [关闭]
【发布时间】:2015-07-08 10:05:44
【问题描述】:

我目前的理解是,宏可以实现任何可以想象的概念,包括 monad,因为它们“手头有编译器”。这是真的?比如我遇到过这个link

请给我事实和例子,不要热情回答。谢谢。

【问题讨论】:

    标签: haskell macros lisp monads


    【解决方案1】:

    这是一种奇怪的比较。这有点像在问“汽油车能做什么柴油发电机不能做的事情?”呃,好吧,那些不是真正的同一类东西......

    Lisp 宏 [我对此几乎一无所知] 允许您进行编译时元编程。您可以使用它来实现各种有用的事情,从消除一些样板代码到虚拟定义一种全新的编程语言。

    Haskell monad 是构建某些类型计算的有用方法。它们使某些原本有点乏味的事情变得容易。 (例如,在运行下一个函数之前检查每个函数的结果以确保它成功。)不过,所有这些都是 run-time 的事情;它与编译时代码生成无关。

    【讨论】:

    • Haskell monad 能否像 Lisp 宏一样用于删除样板代码?
    • @mljrg 如果您在 Haskell 中寻找 Lisp 宏等效项,那么您必须使用 Template Haskell。 Monad 和 macro 是两个不同的东西,比较它们是不合适的。
    • @mljrg 这当然取决于你想要做什么。我不是专家,但我希望宏在原则上更强大。我无法评论它们在实践中是否真的更有用。
    • 我觉得将 lisp 宏与 haskell 的惰性进行比较更接近 - 您可以使用引用的宏来实现惰性评估
    • @mljrg monad 通常不会减少样板代码,尽管其中一些会减少嵌套的 case 语句。
    【解决方案2】:

    如果你可以用 Lisp 实现某些东西,你可以用宏来改进它的语法。因此,宏部分只是为了让它看起来更好或/和减少代码大小。

    您不需要宏来实现单子。 Marijn Haverbeke 使用defstructdefgeneic 制作了monad implementation

    当然defstructdefgeneric 可能会使用宏来实现它的魔力,但实际上并不需要实现monad。您可以使用闭包实现 monad。在下面的代码中,它用作带有封装和消息传递的基本 OO。

    (defun maybe (val)
      (lambda (msg &optional f m)
        (case msg
          ((bind) (if val (funcall f val) m))
          (otherwise val))))
    
    (defun bind (m f)
      (funcall m 'bind f m)) ;message passing
    
    (defun value (m)
      (funcall m 'value))    ; message passig
    

    宏是处理语法的函数。在像 Haskell 这样的惰性语言中,宏可以被函数替换,因为只有在需要时才会评估参数。例如。在具有热切评估的 CL 中,您需要一个宏来创建自己的 if,但您可以使用 Haskell 中的函数来做同样的事情。

    【讨论】:

    • 闭包不是“基本的 OO”。
    • @Svante 对象和词法范围上的闭包serves the same purpose
    • 没有。它们可用于类似目的。您不应该将一个减少到与另一个重叠的部分。
    猜你喜欢
    • 1970-01-01
    • 2011-06-26
    • 2013-03-11
    • 2012-04-11
    • 2012-11-17
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多