【问题标题】:Why is there no >=> semigroup for A => M[A] in Scalaz?为什么 Scalaz 中没有 A => M[A] 的 >=> 半群?
【发布时间】:2015-07-14 13:31:04
【问题描述】:

这是我之前question的后续行动

Kleisli 定义了两个运算符 <=< (compose) 和 >=> (andThen)。 >=> 对我来说看起来很自然,但我不明白 <=< 有什么用处。

此外,A => M[A] 似乎没有 >=> 半组,但 <=< 半组确实存在。

背后的原理是什么?

【问题讨论】:

  • 我怀疑唯一真正的答案是数学传统。两者在a <=< b == b >=> a 中是等价的,不是吗?所以这只是一个约定,例如矩阵乘法被定义为行列而不是列行。

标签: scala scalaz kleisli semigroup


【解决方案1】:

compose(或<=<)在无点和非无点样式之间转换时更自然一些。例如,如果我们有这些函数:

val f: Int => Int = _ + 1
val g: Int => Int = _ * 10

我们得到以下等价:

scala> (f andThen g)(3) == g(f(3))
res0: Boolean = true

scala> (f compose g)(3) == f(g(3))
res1: Boolean = true

compose 的情况下,fg 在等式两边的顺序相同。

不幸的是,Scala 的类型推断通常使andThen(或>=>)更方便,而且它的使用范围往往比compose 更广泛。所以这是一个数学惯例和 Scala 类型推断系统的怪癖不一致的情况。 Scalaz(考虑到项目的文化,这并不奇怪)选择了数学方面。

【讨论】:

  • 谢谢,我明白了。我想知道,如何实施。像这样:假设我有一个函数child(name: String): XmlNode => Option[XmlNode]。我想写List("a", "b", "c").map(name => child(name)).foldMap(...) 来获得一个通过路径"a/b/c" 返回节点的函数。现在我需要颠倒列表 :( 这似乎完全是多余的。`
  • 是的,在这种情况下,>=> 似乎确实更接近于操作的对应关系。我可能会跳过幺半群并直接使用>=>
  • 或者,也可以只定义这样一个幺半群:Monoid.instance(_ >=> _, {node => Some(node)})(还不确定如何正确执行)并将其传递给foldMap。我可能会问一个关于它的新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-23
  • 2011-06-18
  • 2016-11-14
  • 2012-03-31
  • 1970-01-01
相关资源
最近更新 更多