【发布时间】:2010-04-20 13:57:42
【问题描述】:
我无法弄清楚“| m -> w”部分在这样的类定义中的含义:
class (Monoid w, Monad m) => MonadWriter w m | m -> w
这为类定义添加了哪些额外信息?
【问题讨论】:
我无法弄清楚“| m -> w”部分在这样的类定义中的含义:
class (Monoid w, Monad m) => MonadWriter w m | m -> w
这为类定义添加了哪些额外信息?
【问题讨论】:
竖线是句法分隔符,本身没有意义,用于多参数类型类上的introduce functional dependencies,所以技术上| 没有任何意义。据推测,| 被选为视觉上的类比,用于在函数上使用相同的符号 pattern guards。
就函数依赖本身而言,只需将x -> y读作“类型参数x唯一确定类型参数y”,这意味着仅知道x就足以找到正确的实例。还有更多的复杂情况,尤其是在启用其他 GHC 扩展的情况下,但大多数时候您不需要担心它们。
相比之下,在没有函数依赖的情况下,选择多参数类型类的实例需要知道所有类型参数。一个典型的例子有一个参数是容器类型,第二个参数是所包含元素的类型; "concatenate" 或 "isEmpty" 等函数无需提及元素类型,仅提及容器类型,因此会产生歧义。
另外,如果您正在编写自己的类型类,请考虑改用type families,这是一种可能最终取代函数依赖的新方法。粗略地说,类型族允许您在实例中编写重载类型定义,而不仅仅是重载函数。
【讨论】:
monads-tf 用类型族而不是函数依赖实现标准转换器:hackage.haskell.org/package/monads-tf
它指定了一个functional dependency。
【讨论】: