[英]`forever` Combinator with Higher Kinded Type
我正在嘗試從Scala的Functional Programming中運行以下組合器:
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
的類型是什么意思? 可以使用一般的“高級類型”嗎?
罪魁禍首是a flatMap (_ => t)
。
按照給定的代碼,您可以使用flatMap(a)(_ => t)
進行編譯。
除非您使用隱式,否則Monad接口不會自動將Monadic運算符添加到任何參數化類型。
F[_]
是存在類型,這意味着F是包含其他類型的類型,等效於: trait F {type A}
。 每個Monad都是一個Functor,只有參數化類型可以是Functors,這就是為什么您需要使用F[_]
來參數化Monad的原因。 換句話說,只有參數化類型才能滿足Monad / Functor接口。 通過參數化類型(* -> *) -> *
參數化的類型是更高種類的類型。 F[_]
是限制性最小的,因此可以在這里使用的最通用的類型。 通過類型投影,可以使其他參數化的類型看起來像F [_]。 例如,要為右偏的Either類型定義Monad,可以使用type FA = ({type l[a] = Either[L, a]})#l
作為F[_]
。 請參閱此處,以獲取Monad for Either的完整代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.