例如,我已经定义了Monad Trait
,如下所示:
trait Monad[F[_]] {
def unit[T](a: => T): F[T]
def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]
}
我创建了一个ListMonad
,它实现了以上接口:
class ListMonad extends Monad[List] {
override def unit[T](a: => T): List[T] = List(a)
override def flatMap[A, B](fa: List[A])(f: (A) => List[B]): List[B] = fa flatMap f
}
现在我想在" Generic way"中验证Monad以上。 monad的第一个属性是Left Identity
。这意味着:如果我们给一个monad" m",一个值" x"和函数" f"。它应该满足:m.(identity(x)).flatMap(f) == f(x)
例如,我创建了以下验证者类来检查该假设:
case class MonadVerifier[A, F[_]](monad: Monad[F[_]])(f: A => F[A]) {
def leftIdentity(value: A): Boolean =
monad.flatMap[A, A](monad.unit(value))(f) == f(value)
}
在此代码中,我遇到错误:
类型不匹配。预期的:(A)=> F [_] [A],实际:(A)=> F [A]
我在Scala中不知道,我怎样才能将F[A]
表达为通用。我想如果我定义F[_]
Scala会在调用[_]
时将通用类型插入F[A]
,但它不是真的。
在这种情况下请帮助我。感谢
答案 0 :(得分:3)
@Dima说的话:
错误就是
MonadVerifier[A, F[_]](monad: Monad[F[_]])
应该是
MonadVerifier[A, F[_]](monad: Monad[F])
第一行所说的不是F
是monad(F
有* -> *
种类和F[_]
}类型的值,而是F[_]
(即,类型构造函数F
应用于任何类型的正确类型)是一个monad,(F
具有种类* -> (* -> *)
和类型F[_][_]
的值)。 / p>
扩展(如果需要,请忽略它):Monad
期望其类型参数采用一个类型参数并返回具体类型。 Monad
的论据被称为* -> *
("函数"从具体类型到具体类型),而Monad
本身有种类(* -> *) -> *
( "功能"从"功能"从具体类型到具体类型到具体类型)。当你说Monad[F[_]]
时,你暗示论证(F[_]
)有* -> *
种,因为那是Monad
所期望的那种。 F[_]
是类型构造函数F
(对于某些未知类a -> b
和a
的种类b
)应用于任何具体类型(由{{1隐含)强制某种未知_
将F
的约束限制为* -> k
。由于k
,F[_]
也必须为* -> *
,因此约束Monad
,因此k = (* -> *)
被强制为F
* -> (* -> *)
的咖喱版。这意味着(*, *) -> *
有两个类型参数,在第二个参数中是monadic(如F
)。
将来可能会使用上下文来避免类似的混淆:
Either