Would it be feasible to extend this approach to arbitrary polymorphic values? Essentially, providing syntax for scalaz.Forall:
/** A universally quantified value */
trait Forall[P[_]] {
def apply[A]: P[A]
}
The polymorphic function is then just a special case:
type NaturalTransformation[F[_], G[_]] = Forall[λ[A => (F[A] => G[A])]]
The syntax could be
val f = ∀[λ[A => (List[A] => Option[A])]](_.headOption)
or in general
where
F[_] is a unary type constructor;
<expr> is an expression of type Function0[F[_]].
The resulting type of f is then Forall[F].
One benefit of this is that you don't need special named traits for polymorphic functions anymore (there is scalaz.~> and cats.FunctionK, which are basically the same, but incompatible—one needs conversions between them).
The main benefit, however, is that we would have syntax for other polymorphic values, like
∀[λ[A => Lens[F[A], G[A]]]]
Then given
trait Lens[S, A] {
def get(s: S): A
def set(s: S, a: A): S
}
object Lens {
def apply[S, A](get: S => A, set: (S, A) => S): Lens[S, A] = ???
}
we could define a polymorphic lens
val fstLens = ∀[λ[A => Lens[(A, Int), Id[A]]]](Lens(_._1, (ai, a) => (a, ai._2)))
where fstLens has type Forall[λ[A => Lens[(A, Int), Id[A]]]]. This would then be used like this
val x = ("Hello", 5)
fstLens[String].get(x) // "Hello"
fstLens[String].set(x, "Bye") // ("Bye", 5)
Would it be feasible to extend this approach to arbitrary polymorphic values? Essentially, providing syntax for
scalaz.Forall:The polymorphic function is then just a special case:
The syntax could be
or in general
where
F[_]is a unary type constructor;<expr>is an expression of typeFunction0[F[_]].The resulting type of
fis thenForall[F].One benefit of this is that you don't need special named traits for polymorphic functions anymore (there is
scalaz.~>andcats.FunctionK, which are basically the same, but incompatible—one needs conversions between them).The main benefit, however, is that we would have syntax for other polymorphic values, like
Then given
we could define a polymorphic lens
where
fstLenshas typeForall[λ[A => Lens[(A, Int), Id[A]]]]. This would then be used like this