-
-
Save Katrix/b3da2b1c66b11eea69484c63c2c9d262 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object AddRemoveSeperate { | |
type Outer[W[_], E[_], A] = W[E[A]] | |
type Inner[W[_], E[_], A] = E[W[A]] | |
type SingleWrapper[W[_], E[_], A] = W[A] | |
type SingleExisting[W[_], E[_], A] = E[A] | |
trait Add[W[_], To[_[_], _[_], _], In] { | |
type Out | |
} | |
object Add { | |
type Aux[W[_], To[_[_], _[_], _], In, Out0] = Add[W, To, In] { | |
type Out = Out0 | |
} | |
def apply[W[_], To[_[_], _[_], _], In]( | |
implicit add: Add[W, To, In] | |
): Aux[W, To, In, add.Out] = add | |
implicit def valueTypes[W[_], To[_[_], _[_], _], E[_], A]: Add.Aux[W, To, E[A], To[W, E, A]] = | |
new Add[W, To, E[A]] { | |
type Out = To[W, E, A] | |
} | |
} | |
trait RemoveOuter[W[_], In] { | |
type Out | |
} | |
object RemoveOuter { | |
type Aux[W[_], In, Out0] = RemoveOuter[W, In] { | |
type Out = Out0 | |
} | |
def apply[W[_], In]( | |
implicit removeOuter: RemoveOuter[W, In] | |
): Aux[W, In, removeOuter.Out] = removeOuter | |
implicit def valueTypes[W[_], E[_], A]: RemoveOuter.Aux[W, W[E[A]], E[A]] = | |
new RemoveOuter[W, W[E[A]]] { | |
type Out = E[A] | |
} | |
} | |
trait RemoveInner[W[_], In] { | |
type Out | |
} | |
object RemoveInner { | |
type Aux[W[_], In, Out0] = RemoveInner[W, In] { | |
type Out = Out0 | |
} | |
def apply[W[_], In]( | |
implicit removeInner: RemoveInner[W, In] | |
): Aux[W, In, removeInner.Out] = removeInner | |
implicit def valueTypes[W[_], E[_], A]: RemoveInner.Aux[W, E[W[A]], E[A]] = | |
new RemoveInner[W, E[W[A]]] { | |
type Out = E[A] | |
} | |
} | |
val res1 = Add[Option, Outer, Seq[Int]] | |
implicitly[res1.Out =:= Option[Seq[Int]]] | |
val res2 = Add[Option, Inner, Seq[Int]] | |
implicitly[res2.Out =:= Seq[Option[Int]]] | |
val res3 = RemoveOuter[Option, Option[Seq[Int]]] | |
implicitly[res3.Out =:= Seq[Int]] | |
val res4 = RemoveInner[Option, Seq[Option[Int]]] | |
implicitly[res4.Out =:= Seq[Int]] | |
} | |
object AddRemoveOne { | |
type Outer[W[_], E[_], A] = W[E[A]] | |
type Inner[W[_], E[_], A] = E[W[A]] | |
type SingleWrapper[W[_], E[_], A] = W[A] | |
type SingleExisting[W[_], E[_], A] = E[A] | |
trait AddRemove[W[_], From[_[_], _[_], _], To[_[_], _[_], _], In] { | |
type Out | |
} | |
object AddRemove { | |
type Aux[W[_], From[_[_], _[_], _], To[_[_], _[_], _], In, Out0] = AddRemove[W, From, To, In] { | |
type Out = Out0 | |
} | |
def apply[W[_], From[_[_], _[_], _], To[_[_], _[_], _], In]( | |
implicit findReplace: AddRemove[W, From, To, In] | |
): Aux[W, From, To, In, findReplace.Out] = findReplace | |
implicit def valueTypes[W[_], From[_[_], _[_], _], To[_[_], _[_], _], E[_], A] | |
: AddRemove.Aux[W, From, To, From[W, E, A], To[W, E, A]] = | |
new AddRemove[W, From, To, From[W, E, A]] { | |
type Out = To[W, E, A] | |
} | |
} | |
/* | |
None of these work | |
val res1 = AddRemove[Option, SingleExisting, Outer, Seq[Int]] | |
implicitly[res1.Out =:= Option[Seq[Int]]] | |
val res2 = AddRemove[Option, SingleExisting, Inner, Seq[Int]] | |
implicitly[res2.Out =:= Seq[Option[Int]]] | |
val res3 = AddRemove[Option, Outer, SingleExisting, Option[Seq[Int]]] | |
implicitly[res3.Out =:= Seq[Int]] | |
val res4 = AddRemove[Option, Inner, SingleExisting, Seq[Option[Int]]] | |
implicitly[res4.Out =:= Seq[Int]] | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment