Created
October 19, 2016 13:01
-
-
Save wheaties/1c2fdc73241c213b84c67a579e262018 to your computer and use it in GitHub Desktop.
Shapeless Poly Compose Attempt
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
| trait ComposeBuilder[F, G] extends DepFn2[F, G] | |
| object ComposeBuilder extends LowPriorityComposeBuilder{ | |
| implicit def cc[C1 <: Poly, L1 <: HList, C2 <: Poly, L2 <: HList] | |
| (implicit unpack1: Unpack1[C1, Compose1, L1], | |
| unpack2: Unpack1[C2, Compose1, L2], | |
| pre: hl.Prepend[L1, L2]): Aux[C1, C2, Compose1[pre.Out]] = | |
| new ComposeBuilder[C1, C2]{ | |
| type Out = Compose1[pre.Out] | |
| def apply(c1: C1, c2: C2) = new Compose1[pre.Out] | |
| } | |
| } | |
| trait LowPriorityComposeBuilder extends LowPriorityComposeBuilder0{ | |
| implicit def cpoly[C <: Poly, L <: HList, G <: Poly] | |
| (implicit unpack: Unpack1[C, Compose1, L], | |
| pre: hl.Prepend[L, G :: HNil]): Aux[C, G, Compose1[pre.Out]] = | |
| new ComposeBuilder[C, G]{ | |
| type Out = Compose1[pre.Out] | |
| def apply(c: C, g: G) = new Compose1[pre.Out] | |
| } | |
| implicit def polyc[C <: Poly, L <: HList, F <: Poly] | |
| (implicit unpack: Unpack1[C, Compose1, L]): Aux[F, C, Compose1[F :: L]] = | |
| new ComposeBuilder[F, C]{ | |
| type Out = Compose1[F :: L] | |
| def apply(f: F, c: C) = new Compose1[F :: L] | |
| } | |
| } | |
| trait LowPriorityComposeBuilder0{ | |
| type Aux[F, G, Out1] = ComposeBuilder[F, G]{ type Out = Out1 } | |
| implicit def polypoly[F <: Poly, G <: Poly]: Aux[F, G, Compose1[F :: G :: HNil]] = | |
| new ComposeBuilder[F, G]{ | |
| type Out = Compose1[F :: G :: HNil] | |
| def apply(f: F, g: G) = new Compose1[F :: G :: HNil] //new Compose1(f :: g :: HNil) | |
| } | |
| } | |
| class Compose1[L] extends Poly | |
| object Compose1{ | |
| implicit def comp[C, L <: HList, U](implicit unpack: Unpack1[C, Compose1, L], ev: ComposeWalk[L, U]): Case.Aux[C, U :: HNil, ev.Out] = | |
| new Case[C, U :: HNil]{ | |
| type Result = ev.Out | |
| val value = (u: U :: HNil) => ev(u.head) | |
| } | |
| } | |
| trait ComposeWalk[L <: HList, U] extends DepFn1[U] | |
| object ComposeWalk extends LowPriorityComposeWalk{ | |
| implicit def recur[H <: Poly, T <: HList, U, V](implicit ev: Case1.Aux[H, U, V], walk: ComposeWalk[T, V]):Aux[H :: T, U, walk.Out] = | |
| new ComposeWalk[H :: T, U]{ | |
| type Out = walk.Out | |
| def apply(u: U) = walk(ev(u)) | |
| } | |
| } | |
| trait LowPriorityComposeWalk{ | |
| type Aux[L <: HList, U, Out1] = ComposeWalk[L, U]{ type Out = Out1 } | |
| implicit def hnil[U]: Aux[HNil, U, U] = | |
| new ComposeWalk[HNil, U]{ | |
| type Out = U | |
| def apply(u: U) = u | |
| } | |
| } |
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
| @Test | |
| def testCompose1{ | |
| import PolyDefns._ | |
| //val yo = new Compose1(option :: isDefined :: HNil) | |
| def yo[L <: HList, U](u: U)(implicit cw: ComposeWalk[L, U]): cw.Out = cw(u) | |
| val out = yo[option.type :: isDefined.type :: HNil, Int](1) | |
| assertEquals(true, out) | |
| val out2 = yo[option.type :: isDefined.type :: option.type :: HNil, Int](1) | |
| assertEquals(Option(true), out2) | |
| val that = new Compose1[option.type :: isDefined.type :: HNil] | |
| val out3 = that(1) | |
| assertTypedEquals[Boolean](true, out3) | |
| val those = new Compose1[option.type :: isDefined.type :: option.type :: HNil] | |
| val out4 = those(1) | |
| assertTypedEquals[Option[Boolean]](Option(true), out4) | |
| val two = isDefined compose1 option | |
| assertTypedEquals[Compose1[option.type :: isDefined.type :: HNil]](two, two) | |
| val out5 = two(1) | |
| assertTypedEquals[Boolean](true, out5) | |
| //scuttled again. | |
| //val three = option compose1 isDefined compose1 option | |
| //assertTypedEquals[Compose1[option.type :: isDefined.type :: option.type :: HNil]](three, three) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment