为什么联接是独立的,而不是Monad类型类的最小实现的一部分?

时间:2018-07-30 15:11:27

标签: haskell

我宁愿通过join函数而不是gremlin> Gremlin.version() ==>3.3.3 gremlin> g = TinkerFactory.createModern().traversal() ==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard] gremlin> g.V(). ......1> and( ......2> outE('created'), ......3> out('knows').has('name', 'vadas') ......4> ). ......5> union( ......6> outE('created').inV(), ......7> outE('knows').inV().has('name', 'vadas') ......8> ). ......9> path().by('name').by(label) ==>[marko,created,lop] ==>[marko,knows,vadas] gremlin> g.V(). ......1> and( ......2> out().has('name', 'josh'), ......3> out('created').has('name', 'lop') ......4> ). ......5> union( ......6> outE().inV().has('name', 'josh'), ......7> outE('created').inV().has('name', 'lop') ......8> ). ......9> path().by('name').by(label) ==>[marko,knows,josh] ==>[marko,created,lop] 来定义Monad的实例...从这种等效性开始:

>>=

您只能通过联接定义Monad实例吗?

我希望加入x >>= f = join (fmap f x)

进入Monad

为什么{-# MINIMAL (>>=)| join #-}是顶级类别,而不是join类型类呢?

3 个答案:

答案 0 :(得分:23)

不幸的是,由于与广义新类型派生和角色系统相关的技术限制,join不是GHC标准库中Monad类型类的一部分。长话短说,考虑到某些新类型newtype T m a = MkT (m a),GHC不够聪明,无法弄清楚如何证明m (m a)m (T m a)之间的表示相等性,这对于证明第一个参数的表示相等性是必要的的join(类型为m (m a) -> m a

幸运的是,GHC Haskell的最新扩展QuantifiedConstraints可以使角色系统足够智能以支持此功能。有关问题及其潜在解决方案的更详细处理,请参阅Ryan Scott的博客文章How QuantifiedConstraints can let us put join back in Monad

答案 1 :(得分:7)

join不在Monad中,因为对于新型包装的monad转换器(这是一种非常常见的用例),它会以一种微妙的方式破坏GeneralizedNewtypeDeriving。有关详细信息,请参见the GHC wiki

答案 2 :(得分:0)

join未在Applicative类中定义。检查压痕;所有的类方法都缩进,而join不是。所以这不是一个类方法。

可悲的是,join也不在Monad类中,因此无法以这种方式定义该类。所有单子的join定义都相同。

当前,您能做的最好的事情就是定义一个myCustomJoin函数,然后在Monad的{​​{1}}实例定义中使用它。