第二个Monad法:单位

nsf*_*n55 4 monads functional-programming scala

我在scala上阅读James Iry关于Monads 的博客文章.我在第三部分,我对他关于单位的monad第二定律的描述感到困惑.特别是这个说法:

 unit(x) flatMap f = f(x)
Run Code Online (Sandbox Code Playgroud)

当我应用我的心理例子,这是jame之前的monadic类型的例子,这似乎永远不会成功

 val x = 1
 val f = (_:Int) * 2
 f(x) == 2 //true
 List(x) flatMap f == 2 //fail
 Some(x) flatMap f == 2 //fail
Run Code Online (Sandbox Code Playgroud)

事实上,由于类型问题,它们甚至无法编译.

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

我的困惑是,这些似乎与文章中提出的理论相冲突.我缺少一步吗?这些类型不是真正的monad吗?标题为"Monads第二定律:单位"的部分是否不正确?

Jes*_*per 9

Scala flatMap需要一个返回集合的函数,而不是一个返回单个元素的函数,就像你的函数一样f.

使用map:

List(x) map f
Run Code Online (Sandbox Code Playgroud)

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

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

List(x) flatMap f
Run Code Online (Sandbox Code Playgroud)

请注意,它也将返回一个集合,而不是一个整数(你会得到List(2),而不仅仅是2).

  • 你是对的我错过了文章的一个关键部分,他将flatMap/bind方法的签名定义为`flatMap(f:A => M [B])`.所以问题实际上是我的功能没有正确定义. (5认同)

Ben*_*Ben 8

由于类型问题它不能编译的事实应该告诉你一些事情:f不是monad法适用的那种函数!

flatMap当被视为一元操作而不是收集操作时,它采用"一元价值"和从普通价值到一元价值的函数.您的f函数是从普通值到普通值的函数.

传递fflatMap不破一元法律,它只是不意味着任何东西.这是一个无效的表达.同样1 + "fork" - 1不违反算术规律1 + x - 1 = x; 从这个定律我们可以得出结论,1 + "fork" - 1应该等于"fork",而实际上它是一个编译器错误.那将是一个愚蠢的结论; 法律只是谈论类型正确的事情.