Skip to content

Instantly share code, notes, and snippets.

@wheaties
Last active August 29, 2015 14:05
Show Gist options
  • Select an option

  • Save wheaties/4dc26dfd613cdc9d1df0 to your computer and use it in GitHub Desktop.

Select an option

Save wheaties/4dc26dfd613cdc9d1df0 to your computer and use it in GitHub Desktop.
Attempts at Curried On Poly
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)
}
}
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)
}
}
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))
}
}
@wheaties
Copy link
Copy Markdown
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