具體而言,我試圖用Applicative
擴展Functor
類特定類。Scala:將特徵方法推遲到父特徵對象中的隱式類
trait Functor[F[_]] {
def fmap[A, B](r: F[A], f: A => B): F[B]
}
object Functor {
implicit class FunctorOps[A, F[_]: Functor](xs: F[A]) {
def fmap[B](f: A => B): F[B] = implicitly[Functor[F]].fmap(xs, f)
}
implicit def SeqFunctor: Functor[Seq] = new Functor[Seq] {
def fmap[A, B](r: Seq[A], f: A => B) = r map f
}
}
trait Applicative[F[_]] extends Functor[F] {
// What I want to do, but this *does not* work.
def fmap[A, B](r: F[A], f: A => B): F[B] = Functor.FunctorOps[A, F](r).fmap(f)
def pure[A](x: A): F[A]
def fapply[A, B](r: F[A], f: F[A => B]): F[B]
}
object Applicative {
implicit class ApplicativeOps[A, F[_]](a: F[A])(implicit F: Applicative[F]) {
def fapply[B](f: F[A => B]): F[B] = F.fapply(a, f)
}
implicit def SeqApplicative: Applicative[Seq] = new Applicative[Seq] {
def pure[A](x: A) = Seq(x)
def fapply[A, B](xs: Seq[A], fs: Seq[A => B]): Seq[B] = xs.flatMap(x => fs.map(_(x)))
}
}
它的要點是我要實現fmap
所有Applicative
S,但它確實應該在我的FunctorOps
類中定義的方法相同。我如何以最乾淨的方式做到這一點?
我想要做的基礎上延伸的給定typec的想法我在做什麼沒有改變它的來源。所以: 1)我不能改變任何關於我的'Functor'的代碼,包括刪除隱式類。即如果我得到一個我想要擴展的隨機類型類型呢? 2)'fmap'(或者我從給定的類型類繼承的任何函數)可能不像我的類型類的函數那麼容易定義。 – allidoiswin
2)是沒有意義的。如果你不能根據子類來定義超類的方法,那麼你只需要讓它們抽象並讓實現者去做就可以了(就像在Haskell中,它是* only *(便攜)方式)。 1)如果你有一些現有的,不可修改的超類實例,唯一可行的方法是定義你的子類實例以遵循超類(你可以在它自己的幫助類('Helper [F [_]](f :Functor [F]){...}'),但*不要*對子類本身施加這種限制),並確保不要將子類和超類實例一起導入。 – HTNW