簡體   English   中英

永久類型的“永遠”組合器

[英]`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
}

編輯添加MonadFunctor代碼

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[_]作為AddlCombinatorsMonad的類型是什么意思? 可以使用一般的“高級類型”嗎?

罪魁禍首是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM