How to decompose type constructor via implicits?

I have a class Foothat accepts a type constructor Fas a type parameter:

case class Foo[F[_]](x: F[String])

Now I want to define a member method barthat is applicable only if F[T] = Outer[Inner[T]]for some fixed external type Outer, for example. Option:

def bar[Inner[_]](implicit ev: ???): Foo[Inner]

???should be a bit of a natural conversion F ~> Outer·Innerwith ·being a composition of type constructors.

  • What does this implicit argument look like?
  • How can I get it from somewhere?

How to write composition of type constructor?

Also, what is the best way to write the composition of type constructors? I am currently writing using the lambda type ({type L[X] = Outer[Inner[X]]})#L.

+4
1

, ScalaZ, , scalaz.Leibniz . :

sealed abstract class LeibnizK[F[_], G[_]] {
  def subst[Z[_[_]]](p: Z[F]): Z[G]
}

object LeibnizK {
  implicit def refl[F[_]] = new LeibnizK[F, F] {
    override def subst[Z[_[_]]](p: Z[F]): Z[F] = p
  }
}

, , , :

type Outer[A] = Option[A]
type Id[A] = A

case class Foo[F[_]](me: F[String]) {
  // Oh boy, here comes type lambda
  def bar[Inner[_]](implicit leibk: LeibnizK[
    F,
    ({type L[A] = Outer[Inner[A]]})#L
  ]): Outer[Foo[Inner]] = leibk.subst(this).me.map(Foo(_)) // <- OK to use methods of Outer
}

assert(Foo[Option](Some("meh")).bar[Id] == Some(Foo[Id]("meh")))

. :

λ[A => Outer[Inner[A]]
// or
Lambda[A => Outer[Inner[A]]

({type L[A] = Outer[Inner[A]]})#L

( )

(?, Int)

({type L[A] = (A, Int)})#L
+3

Source: https://habr.com/ru/post/1666719/


All Articles