【发布时间】:2024-04-27 05:00:02
【问题描述】:
我正在尝试从Functional Programming in Scala 运行以下组合器:
trait AddlCombinators[F[_]] extends Monad[F[_]] {
def forever[A, B](a: F[A]): F[B] = {
lazy val t: F[B] = forever(a)
a flatMap (_ => t)
}
}
但它没有编译:
[error] AddlCombinators.scala:7: value flatMap is not a member of type
parameter F[A]
[error] a flatMap (_ => t)
[error] ^
我的理解是我需要使用F[_],因为它表示一种更高种类的类型。
例如,我在本书的前一章写过Monad[List]:
object ListMonad extends Monad[List] {
def unit[A](a: => A): List[A] = List(a)
def flatMap[A,B](ma: List[A])(f: A => List[B]): List[B] =
ma.map(x => f(x)).flatten
}
编辑添加Monad和Functor代码
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
trait Monad[F[_]] extends Functor[F] {
def unit[A](a: => A): F[A]
def flatMap[A,B](ma: F[A])(f: A => F[B]): F[B]
如何解决上述编译时错误?另外,F[_] 作为AddlCombinators 和Monad 的类型是什么意思?可以用一般的“higher kinded type”吗?
【问题讨论】:
-
我建议您包含
Monad的定义。通常最好发布自包含代码 sn-ps(尤其是考虑到并非每个人都拥有“Scala 中的函数式编程”的副本)。不仅如此,我还期望Monad被定义为trait Monad[F[_]] { ... },但这与你对trait AddlCombinators[F[_]] extends Monad[F[_]]的定义不一致 -
@RégisJean-Gilles - 谢谢你的建议。我编辑包括
Monad和Functor。 -
嗯,我是对的,你对
AddlCombinators的定义是错误的,应该是AddlCombinators[F[_]] extends Monad[F]。此外,Jamil 是对的,您可以通过执行flatMap( a ) (_ => t)而不是a flatMap (_ => t)来修复您的代码。虽然有些库可能会添加语法糖来允许这种表示法(特别是 scalaz,请参阅 github.com/scalaz/scalaz#syntax),其中a flatMap (_ => t)基本上只会转发到flatMap( a ) (_ => t),可以这么说。
标签: scala