Last active
September 15, 2017 21:06
-
-
Save sir-wabbit/bdd0b43367fe480e3ef3e081339fbd19 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| import Abstract._ | |
| trait Abstract[A, T] { | |
| type Result[_] | |
| } | |
| private[covenant] trait L4 { | |
| implicit def otherwise[A, B]: Abstract.Aux[A, B, λ[X => B]] = | |
| new Abstract.Aux1[A, B, λ[X => B]] | |
| } | |
| private[covenant] trait L3 extends L4 { | |
| implicit def f1[A, F[_], B](implicit B: Abstract[A, B]): Abstract.Aux[A, F[B], λ[X => F[B.Result[X]]]] = | |
| new Abstract.Aux1[A, F[B], λ[X => F[B.Result[X]]]] | |
| } | |
| private[covenant] trait L2 extends L3 { | |
| implicit def f2[A, F[_, _], B1, B2](implicit B1: Abstract[A, B1] {}, B2: Abstract[A, B2] {}): Abstract.Aux[A, F[B1, B2], λ[X => F[B1.Result[X], B2.Result[X]]]] = | |
| new Abstract.Aux1[A, F[B1, B2], λ[X => F[B1.Result[X], B2.Result[X]]]] | |
| } | |
| private[covenant] trait L1 extends L2 { | |
| implicit def f3[A, F[_, _, _], B1, B2, B3](implicit B1: Abstract[A, B1] {}, B2: Abstract[A, B2] {}, B3: Abstract[A, B3] {}): Abstract.Aux[A, F[B1, B2, B3], λ[X => F[B1.Result[X], B2.Result[X], B3.Result[X]]]] = | |
| new Abstract.Aux1[A, F[B1, B2, B3], λ[X => F[B1.Result[X], B2.Result[X], B3.Result[X]]]] | |
| } | |
| object Abstract extends L1 { | |
| def apply[A, T](implicit T: Abstract[A, T] {}): Abstract.Aux[A, T, T.Result] = T | |
| type Aux[T, A, F[_]] = Abstract[T, A] { type Result[X] = F[X] } | |
| final class Aux1[T, A, F[_]] extends Abstract[T, A] { type Result[X] = F[X] } | |
| implicit def id[A]: Abstract.Aux[A, A, λ[X => X]] = | |
| new Aux1[A, A, λ[X => X]] | |
| protected[this] type H | |
| implicit def f1k[A, B[_], F[_[_]]](implicit B: Abstract2[A, H, B[H]]): Abstract.Aux[A, F[B], λ[X => F[B.Result[X, ?]]]] = | |
| new Abstract.Aux1[A, F[B], λ[X => F[B.Result[X, ?]]]] | |
| } | |
| trait Abstract2[A, B, T] { | |
| type Result[_, _] | |
| } | |
| private[covenant] trait Abstract2_4 { | |
| implicit def otherwise[A, B, T]: Abstract2.Aux[A, B, T, λ[(X, Y) => T]] = | |
| new Abstract2.Aux1[A, B, T, λ[(X, Y) => T]] | |
| } | |
| private[covenant] trait Abstract2_3 extends Abstract2_4 { | |
| implicit def f1[A, B, F[_], I](implicit I: Abstract2[A, B, I]): Abstract2.Aux[A, B, F[I], λ[(X, Y) => F[I.Result[X, Y]]]] = | |
| new Abstract2.Aux1[A, B, F[I], λ[(X, Y) => F[I.Result[X, Y]]]] | |
| } | |
| private[covenant] trait Abstract2_2 extends Abstract2_3 { | |
| implicit def f2[A, B, F[_, _], I1, I2] | |
| (implicit | |
| I1: Abstract2[A, B, I1] {}, | |
| I2: Abstract2[A, B, I2] {} | |
| ): Abstract2.Aux[A, B, F[I1, I2], λ[(X, Y) => F[I1.Result[X, Y], I2.Result[X, Y]]]] = | |
| new Abstract2.Aux1[A, B, F[I1, I2], λ[(X, Y) => F[I1.Result[X, Y], I2.Result[X, Y]]]] | |
| } | |
| private[covenant] trait Abstract2_1 extends Abstract2_2 { | |
| implicit def f3[A, B, F[_, _, _], I1, I2, I3] | |
| (implicit | |
| I1: Abstract2[A, B, I1] {}, | |
| I2: Abstract2[A, B, I2] {}, | |
| I3: Abstract2[A, B, I3] {} | |
| ): Abstract2.Aux[A, B, F[I1, I2, I3], λ[(X, Y) => F[I1.Result[X, Y], I2.Result[X, Y], I3.Result[X, Y]]]] = | |
| new Abstract2.Aux1[A, B, F[I1, I2, I3], λ[(X, Y) => F[I1.Result[X, Y], I2.Result[X, Y], I3.Result[X, Y]]]] | |
| } | |
| object Abstract2 extends Abstract2_1 { | |
| def apply[A, B, T](implicit T: Abstract2[A, B, T] {}): Abstract2.Aux[A, B, T, T.Result] = T | |
| type Aux[A, B, T, F[_, _]] = Abstract2[A, B, T] { type Result[X, Y] = F[X, Y] } | |
| final class Aux1[A, B, T, F[_, _]] extends Abstract2[A, B, T] { type Result[X, Y] = F[X, Y] } | |
| implicit def id1[A, B]: Abstract2.Aux[A, B, A, λ[(X, Y) => X]] = | |
| new Aux1[A, B, A, λ[(X, Y) => X]] | |
| implicit def id2[A, B]: Abstract2.Aux[A, B, B, λ[(X, Y) => Y]] = | |
| new Aux1[A, B, B, λ[(X, Y) => Y]] | |
| } | |
| /////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
| scala> Abstract[Int, Int] | |
| res2: Abstract[Int, Int]{type Result[X] = X} = ... | |
| scala> Abstract[Int, (Int, Option[Int])] | |
| res0: Abstract[Int, (Int, Option[Int])]{type Result[X] = (X, Option[X])} = ... | |
| scala> Abstract[Int, (Int, Option[Int], Long)] | |
| res1: Abstract[Int,(Int, Option[Int], Long)]{type Result[X] = (X, Option[X], Long)} = ... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
uh, what is this??