구체적으로 타입 클래스를 Applicative
으로 확장하려고합니다.스칼라 : 부모 특성 개체의 암시 적 클래스에 특성 메서드 연기
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)))
}
}
그것의 요점은 내가 모든 Applicative
들에 대한 fmap
을 구현해야하지만, 내 FunctorOps
클래스에 정의 된대로 정말 같은 방법으로해야합니다. 어떻게하면 가능한 한 가장 깨끗한 방법으로이 작업을 수행 할 수 있습니까?
ApplicativeOps
에 그것의 근원을 바꾸기없이 lass. 그래서 : 1) 암시적인 클래스를 제거하는 것을 포함하여, 나의'Functor' 코드에 대해서는 아무것도 변경할 수 없습니다. 즉, 내가 확장하고 싶은 임의의 typeclass를 얻으면? 2)'fmap' (또는 내가 주어진 typeclass로부터 상속 받고있는 함수)은 제 typeclass 함수의 관점에서 정의하기가 쉽지 않을 수 있습니다. – allidoiswin2)가 아닙니다. 수퍼 클래스의 메소드를 서브 클래스의 관점에서 정의 할 수 없다면, 추상화 된 상태로두고 구현자를 얻으십시오 (하스켈처럼, 오직 유일한 (휴대용) 방법입니다). 1) 기존의 수정 불가능한 수퍼 클래스 인스턴스가있는 경우 슈퍼 클래스로 연기하도록 서브 클래스 인스턴스를 정의해야합니다 (자신의 도우미 클래스에서이를 멀리 추상화 할 수 있습니다 ('Helper [F [_]] (f : Functor [F]) {...}'), 서브 클래스 자체에 그 제한을 부과하지 않습니다.) 서브 클래스와 수퍼 클래스 인스턴스를 함께 가져 오지 않도록하십시오. – HTNW