让我们说我们有一个功能
f: (A, A) => A
我们有两个可选值
val x: Option[A] = ...
val y: Option[A] = ...
现在我们要将函数f
应用于x
,y
。如果其中一个参数为None
,我们希望返回None
。在scalaz中我们可以写
^(x, y)(f)
现在假设我们想要通过另一个检查参数是否满足约束的函数来限制函数f
的输入参数。如果是,则该函数将f
应用于其参数,并返回包含在Some
对象中的结果。否则返回None
:
fRestricted: (A, A) => Option[A]
现在的问题是我们不能再使用Scalaz了,即
^(x, y)(fRestricted)
不再起作用,因为类型错误。
这实际上是一个常见的问题吗?是否有针对用例的通用解决方案?
答案 0 :(得分:2)
这是函数式编程中最基本的问题之一(不仅仅是Scala)。
您使用Scalaz所做的事情是基于Option
的应用函子功能。不幸的是,标准的Scala库不支持applicative functor,但它确实支持monad,Option
也是monad。应用仿函数比monad更严格,所以无论应用函数都可以做,monad也可以做。
以下是如何利用Option
是monad来解决标准库问题的事实:
for {
a <- x
b <- y
c <- fRestricted(a, b)
}
yield c
上面的语法被称为&#34; for-comprehension&#34;,实际上它只不过是以下的糖:
x.flatMap( a => y.flatMap( b => fRestricted(a, b) ) )