私は次のコンビネーターを実行しようとしています 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
}
EDIT 追加する 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
?一般的な「上位の種類」を使用できますか?
回答:
回答№1は2a flatMap (_ => t)
ここが犯人です。
与えられたコードに従って、使用することができます flatMap(a)(_ => t)
コンパイルします。
Monadインターフェイスは、暗黙的に使用しない限り、パラメーター化された型にモナド演算子を自動的に追加しません。
F[_]
は、Fが他の型を含む型であることを意味する実存型です。 trait F {type A}
。すべてのMonadはFunctorであり、パラメーター化された型のみがFunctorになることができるため、次のようにMonadをパラメーター化する必要があります。 F[_]
。別の言い方をすれば、パラメーター化された型のみがMonad / Functorインターフェースを満たすことができます。パラメーター化された型によってパラメーター化された型 (* -> *) -> *
上位の種類です。 F[_]
制限が最も少ないため、最も一般的なタイプここで使用できます。他のパラメーター化された型は、型射影を介してF [_]のように見せることができます。たとえば、右バイアスのどちらかのタイプのMonadを定義するには、次を使用できます。 type FA = ({type l[a] = Either[L, a]})#l
として F[_]
。見る ここに いずれかのMonadの完全なコード。