Last active
August 29, 2015 14:05
-
-
Save wheaties/4dc26dfd613cdc9d1df0 to your computer and use it in GitHub Desktop.
Attempts at Curried On Poly
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
| class Curried[P, N <: Nat, L <: HList](p: P, args: L) extends Poly1{ | |
| def yo[H](h: H)(implicit step: Step[P, L, H]) = h //aaarrrggg!! | |
| } | |
| trait Step[P, L <: HList, H] | |
| object Step{ | |
| def apply[P, L <: HList, H](implicit step: Step[P, L, H]) = step | |
| implicit def first[P, R <: HList](implicit ev: Case[P, R], cons: hl.IsHCons[R]): Step[P, HNil, cons.H] = | |
| new Step[P, HNil, cons.H]{} | |
| implicit def mk[P, L <: HList, R <: HList, LR <: HList] | |
| (implicit prepend: hl.Prepend.Aux[L, R, LR], | |
| ev: Case[P, LR], | |
| lcons: hl.IsHCons[L], | |
| cons: hl.IsHCons[R]): Step[P, L, cons.H] = new Step[P, L, cons.H]{} | |
| } | |
| trait CurriedBuilder[P <: Poly, N <: Nat] extends (P => Curried[P, N, HNil]) | |
| object CurriedBuilder{ | |
| def apply[P <: Poly, N <: Nat](implicit builder: CurriedBuilder[P, N]) = builder | |
| //we can prove that there exists some HList "L" of length "N" given a "P". But we can't prove that the first argument | |
| //to "L" is "H" above? Why? | |
| implicit def curBuilder[P <: Poly, N <: Nat, L <: HList](implicit ev: Case[P, L], length: hl.Length.Aux[L, N]) = | |
| new CurriedBuilder[P, N]{ | |
| def apply(p: P) = new Curried[P, N, HNil](p, HNil) | |
| } | |
| } |
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
| class Curried[P, N <: Nat, L <: HList](args: L) extends Poly1{ | |
| implicit def cont[A](implicit step: Step[P, L, A, N]) = use({a: A => step(a :: args)}) | |
| def yo[A](implicit ste: Step[P, L, A, N]) = ste //called by itself, this fails so above fails as well. | |
| } | |
| trait Step[P, L <: HList, H, N <: Nat] extends DepFn1[H :: L] | |
| object Step extends LowPriorityStep{ | |
| def apply[P, L <: HList, H, N <: Nat](implicit step: Step[P, L, H, N]) = step | |
| implicit def finCase[P, N <: Nat, L <: HList, OutL <: HList, H, T <: HList] | |
| (implicit ev: Case[P, OutL], | |
| reverse: hl.Reverse.Aux[H :: T, OutL], | |
| length: hl.Length.Aux[L, N], | |
| cons: hl.IsHCons.Aux[L, H, T]): Step[P, T, H, N] = | |
| new Step[P, T, H, N]{ | |
| type Out = ev.Result | |
| def apply(l: H :: T) = ev(reverse(l)) | |
| } | |
| } | |
| trait LowPriorityStep{ | |
| implicit def nextCase[P, N <: Nat, L <: HList, RevL <: HList, R <: HList, LR <: HList] | |
| (implicit reverse: hl.Reverse.Aux[L, RevL], | |
| prepend: hl.Prepend.Aux[RevL, R, LR], | |
| ev: Case[P, LR], | |
| length: hl.Length.Aux[LR, N], | |
| cons: hl.IsHCons[R]) = | |
| new Step[P, L, cons.H, N]{ | |
| type Out = Curried[P, N, cons.H :: L] | |
| def apply(h: cons.H :: L) = new Curried[P, N, cons.H :: L](h) | |
| } | |
| } |
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
| class Curried[P <: Poly, N <: Nat, L <: HList](p: P, args: L) extends Poly1{ | |
| implicit def next[H](implicit gen: (P, L) => Case[this.type, H :: HNil]): Case[this.type, H :: HNil] = gen(p, args) | |
| } | |
| object Curried{ | |
| //later | |
| def apply[P <: Poly, N <: Nat, L <: HList](implicit ev: Case[P, L], length: hl.Length.Aux[L, N]) = new Curried[P, N, HNil](p, HNil) | |
| implicit def curryCase[C <: Poly, P <: Poly, N <: Nat, L <: HList, H, T <: HList, PL <: HList, OutL <: HList] | |
| (implicit unpack: Unpack3[C, Curried, P, N, L], | |
| pre: hl.Prepend.Aux[L, H :: T, PL], | |
| prepend: hl.Prepend.Aux[L, H :: HNil, OutL], | |
| ev: Case[P, PL], | |
| length: hl.Length.Aux[PL, N]): (P, L) => Case.Aux[C, H :: HNil, Curried[P, N, OutL]] = | |
| (p: P, l: L) => new Case[C, H :: HNil]{ | |
| type Result = Curried[P, N, OutL] | |
| val value = (h: H :: HNil) => new Curried[P, N, OutL](p, prepend(l, h)) | |
| } | |
| implicit def finalCase[C <: Poly, P <: Poly, N <: Nat, L <: HList, H, PL <: HList] | |
| (implicit unpack: Unpack3[C, Curried, P, N, L], | |
| prepend: hl.Prepend.Aux[L, H :: HNil, PL], | |
| ev: Case[P, PL], | |
| length: hl.Length.Aux[PL, N]): (P, L) => Case.Aux[C, H :: HNil, ev.Result] = | |
| (p: P, l: L) => new Case[C, H :: HNil]{ | |
| type Result = ev.Result | |
| val value = (h: H :: HNil) => ev(prepend(l, h :: HNil)) | |
| } | |
| } |
Author
Author
Idea 35555: try creating an implicit PartialCase[L <: HList, R <: HList, N <: Nat]. Then we can base this type of thing on PartialCase or barring that (same issues as before?) We can do something along the lines of a ZipperCase?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Idea #15930945: Note to self, instead of an element at a time, see if you can do with just an HList. If a Case[P, prepend.Out] can be found/proven, then can move forward by appending "H" onto the list before seeing if there's a Case!