【问题标题】:How to write monoid protocol in Clojure?如何在 Clojure 中编写 monoid 协议?
【发布时间】:2012-06-01 19:49:12
【问题描述】:

由于显而易见的原因,以下方法不起作用。

(defprotocol Monoid
  (mappend [a b])
  (mzero []))

mzero 的参数为零,协议中不允许(或没有意义)零参数方法。在 Haskell 或 Scala 中,调度是基于类型而不是基于值的,这不是问题。

在 Clojure 中概念化和编写 Monoid 协议的正确方法是什么?

【问题讨论】:

  • 为什么你需要它作为一个协议而不是一个模块?如果您期望不同的实现,那么 haskell 将如何推断特定用例中需要哪个实现? (我认为这是一个很好的问题,我只是想追查所涉及的问题)。
  • @andrewcooke Haskell 根据使用现场的静态类型进行推断。调用的方法是静态解析的。
  • @andrewcooke,模块在你的陈述中是什么意思?
  • @missingfaktor - 我说的是错误的。我应该说的是mappend 将在协议中,但mzero 的等价物将是一个创建该协议实现的函数(并且存在于命名空间 - 模块 - 与实现)。从上面我所缺少的是,mzero 之类的东西是如何被上下文单独从特定实现中暗示出来的。
  • @andrewcooke,这个例子可能有助于理解它在 Haskell 中是如何工作的:ideone.com/j1nnz

标签: clojure functional-programming monoids


【解决方案1】:

查看sourcenew reducers library 中的实现方式不是协议,而是重载函数。无参数调用是 mzero;两个 args 调用是 mappend。

更准确地说,monoid 接受两个参数 - opctor 并返回一个函数,该函数在不带参数调用时计算 ctor,当使用两个参数调用时,委托给 op

这与在折叠中处理零的方式是一致的,例如 - reduce (fold) 将评估正在折叠的函数,没有 args 以在必要时找到零。

我觉得展示一些如此平淡无奇的东西有点羞耻,但我不明白如何在 clojure 中做得更好。感谢 cmets 的解释/教育。

【讨论】:

  • 好的,这就回答了这个问题。谢谢!
猜你喜欢
  • 2012-08-02
  • 2011-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-29
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
相关资源
最近更新 更多