Scala:使用某种泛型类型制作更高的kinded类型

时间:2017-07-05 14:42:19

标签: scala functional-programming monads higher-kinded-types

例如,我已经定义了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],但它不是真的。

在这种情况下请帮助我。感谢

1 个答案:

答案 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 -> ba的种类b)应用于任何具体类型(由{{1隐含)强制某种未知_F的约束限制为* -> k。由于kF[_]也必须为* -> *,因此约束Monad,因此k = (* -> *)被强制为F * -> (* -> *)的咖喱版。这意味着(*, *) -> *有两个类型参数,在第二个参数中是monadic(如F)。

将来可能会使用上下文来避免类似的混淆:

Either