/ /上位型を持つ「forever」コンビネーター-scala

より永遠の種類の「永遠の」コンビネータ - スカラ

私は次のコンビネーターを実行しようとしています 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は2

a 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の完全なコード。