【发布时间】:2013-11-21 17:04:24
【问题描述】:
我知道Monad可以用Scala表示如下:
trait Monad[F[_]] {
def flatMap[A, B](f: A => F[B]): F[A] => F[B]
}
我明白它为什么有用了。例如,给定两个函数:
getUserById(userId: Int): Option[User] = ...
getPhone(user: User): Option[Phone] = ...
我可以很容易地编写函数getPhoneByUserId(userId: Int),因为Option 是一个单子:
def getPhoneByUserId(userId: Int): Option[Phone] =
getUserById(userId).flatMap(user => getPhone(user))
...
现在我在 Scala 中看到了 Applicative Functor:
trait Applicative[F[_]] {
def apply[A, B](f: F[A => B]): F[A] => F[B]
}
我想知道什么时候应该使用它 而不是 monad 。我猜 Option 和 List 都是Applicatives。您能否举个简单的例子,将apply 与 Option 和 List 结合使用,并解释为什么我应该使用它而不是flatMap?
【问题讨论】:
-
检查“scalaz”example,tutorial example,scalaz tutorial
-
monad 不仅是一个带有
flatMap方法的特征,也是一个unit方法以及一些必须验证的规律。 -
@YannMoisan 没错。为了简单起见,我省略了它们。
-
@GabrielRiba 我检查了 scalaz 示例。我看到他们如何使用
<*>,但我仍然不明白为什么带有<*>的示例比没有它的示例要好。所有的例子似乎都解决了这个问题。 -
似乎 scalaz () 在右侧采用提升的功能,(与 Haskell 相反)但 () 是左关联的(右关联操作以 ':' 结尾),因此您需要将所有 () 项用右括号括起来。 (|@|) 的替代语法更简洁。
标签: scala functional-programming applicative