4

我正在阅读James Iry在 scala 中关于 Monads的博客文章。我在第三部分,我对他关于单元的单子第二定律的描述感到困惑。特别是这种说法:

 unit(x) flatMap f = f(x)

当我应用我的心理示例时,这些示例是 jame 以前的一元类型示例,这似乎永远不会奏效

 val x = 1
 val f = (_:Int) * 2
 f(x) == 2 //true
 List(x) flatMap f == 2 //fail
 Some(x) flatMap f == 2 //fail

事实上,由于类型问题,它们甚至没有编译。

为了澄清,我理解为什么这些都失败了。我了解如何修复它们以便它们编译。

我的困惑是,这些似乎与文章中提出的理论相冲突。我缺少一个步骤吗?这些类型不是真正的单子吗?题为“单子第二定律:单位”的部分不正确吗?

4

2 回答 2

9

ScalaflatMap需要一个返回集合的函数,而不是返回单个元素的函数,比如你的 function f

要么使用map

List(x) map f

或者让你的函数返回一个集合:

val f = (x: Int) => List(x * 2)

List(x) flatMap f

请注意,它还将返回一个集合,而不是单个整数(您将得到List(2),而不仅仅是2)。

于 2012-06-08T13:02:40.217 回答
8

由于类型问题而无法编译的事实应该告诉你一些事情:f不是单子法则适用的那种函数!

flatMap,当被视为单子操作而不是集合操作时,它采用“单子值”和从普通值到单子值的函数。你的f函数是一个从普通值到普通值的函数。

传递fflatMap不会违反一元法则,它根本没有任何意义。这是一个无效的表达。同样1 + "fork" - 1不违反算术定律1 + x - 1 = x;根据这条定律,我们可能会得出结论,1 + "fork" - 1应该等于“fork”,而实际上它是编译器错误。不过,那将是一个愚蠢的结论;法律只谈论类型正确的事情。

于 2012-06-08T13:11:09.947 回答