具体而言,我试图用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