Skip to content

Instantly share code, notes, and snippets.

@hisui
Last active December 20, 2015 15:49
Show Gist options
  • Save hisui/6156997 to your computer and use it in GitHub Desktop.
Save hisui/6156997 to your computer and use it in GitHub Desktop.
A minimum configuration of Shapeless-like heterological list.
package jp.segfault.optparsec
import scala.language.implicitConversions
import scala.language.postfixOps
import scala.language.higherKinds
object HLists {
import N._
trait HList {
def foldl[X](value:X)(f: (X, Any) => X):X = value
}
object HList {
}
object `[]` extends HList {
override def toString() = "[]"
}
type `[]` = `[]`.type
case class ::[+A,+B <: HList](head:A, tail:B) extends HList {
override def toString() = tail.foldl("[" + head)(_ + "," + _ ) + "]"
override def foldl[X]
(value:X)(f: (X, Any) => X):X = tail.foldl(f(value, head))(f)
}
trait HLMap[F[_,_],X <: HList,Z <: HList] {
def apply(f: Any => Any, o:X):Z
}
object HLMap {
implicit def case0[F[_,_]] = new HLMap[F,`[]`,`[]`] {
def apply(f: Any => Any, o:`[]`):`[]` = `[]`
}
implicit def case1[F[_,_],H1,T1 <: HList,H2,T2 <: HList]
(implicit ev:HLMap[F,T1,T2], ev2:F[H1,H2]) = new HLMap[F,H1::T1,H2::T2] {
def apply(f: Any => Any, o:H1::T1):H2::T2 = f(o.head).asInstanceOf[H2] :: ev(f, o.tail)
}
}
trait Zip[A <: HList,B <: HList,Z <: HList] {
def apply(a:A, b:B):Z
}
object Zip {
implicit def case0[H,T <: HList] = new Zip[`[]`,H::T,`[]`] {
def apply(a:`[]`, b:H::T):`[]` = `[]`
}
implicit def case1[H,T <: HList] = new Zip[H::T,`[]`,`[]`] {
def apply(a:H::T, b:`[]`):`[]` = `[]`
}
implicit def case2 = new Zip[`[]`,`[]`,`[]`] {
def apply(a:`[]`, b:`[]`):`[]` = `[]`
}
implicit def case3[H1,T1 <: HList,H2,T2 <: HList,T3 <: HList]
(implicit zip:Zip[T1,T2,T3]) = new Zip[H1::T1,H2::T2,(H1,H2)::T3] {
def apply(a:H1::T1, b:H2::T2):(H1,H2)::T3 = (a.head, b.head) :: zip(a.tail, b.tail)
}
}
trait Reverse[Y,X <: HList,Z <: HList] {
def apply(o:Y, acc:X):Z
}
object Reverse {
implicit def case0[X <: HList] = new Reverse[`[]`,X,X] {
def apply(o:`[]`, acc:X):X = acc
}
implicit def case1[H,T <: HList,X <: HList,Z <: HList]
(implicit ev:Reverse[T,H::X,Z]) = new Reverse[H::T,X,Z] {
def apply(o: H::T, acc:X):Z = ev(o.tail, o.head :: acc)
}
}
trait Append[Y <: HList,X <: HList,Z <: HList] {
def apply(a:Y, b:X):Z
}
object Append {
implicit def case0[X <: HList] = new Append[`[]`,X,X] {
def apply(a:`[]`, b:X):X = b
}
implicit def case1[H,T <: HList,X <: HList,Z <: HList]
(implicit ev:Append[T,X,Z]) = new Append[H::T,X,H::Z] {
def apply(a: H::T, b:X):H::Z = a.head :: ev(a.tail, b)
}
}
trait Head[X <: HList,Z] {
type Out = Z
def apply(o:X):Z
}
object Head {
implicit def case0[H,T <: HList] = new Head[H::T,H] {
override type Out = H
def apply(o: H::T):H = o.head
}
}
trait Tail[X <: HList,Z <: HList] {
type Out = Z
def apply(o:X):Z
}
object Tail {
implicit def case0[H,T <: HList] = new Tail[H::T,T] {
def apply(o: H::T):T = o.tail
}
}
trait Last[X <: HList,Z] {
type Out = Z
def apply(o:X):Z
}
object Last {
implicit def case0[A <: HList,B <: HList,C]
(implicit reverse:Reverse[A,`[]`,B], head:Head[B,C]) = new Last[A,C] {
override type Out = C
def apply(o:A):C = head(reverse(o, `[]`))
}
}
trait Take[X <: HList,N <: Num,Z <: HList] {
type Out = Z
def apply(o:X):Z
}
object Take {
implicit def case0[Z <: HList] = new Take[Z,`0`,`[]`] {
def apply(o:Z):`[]` = `[]`
}
implicit def case1[H,T <: HList,Z <: HList,I <: Num,J <: Num]
(implicit ev1: (I - `1`) as J, ev2:Take[T,J,Z]) = new Take[H::T,I,H::Z] {
def apply(o: H::T): H::Z = o.head :: ev2(o.tail)
}
}
trait Drop[X <: HList,N <: Num,Z <: HList] {
type Out = Z
def apply(o:X):Z
}
object Drop {
implicit def case0[X <: HList] = new Drop[X,`0`,X] {
def apply(o:X):X = o
}
implicit def case1[H,T <: HList,Z <: HList,I <: Num,J <: Num]
(implicit ev1: (I - `1`) as J, ev2:Drop[T,J,Z]) = new Drop[H::T,I,Z] {
def apply(o: H::T):Z = ev2(o.tail)
}
}
trait Len[X <: HList,Z <: Num] {
def apply(o:X):Int
}
object Len {
implicit def case0 = new Len[`[]`,`0`] {
def apply(o:`[]`):Int = 0
}
implicit def case1[H,T <: HList,I <: Num,J <: Num]
(implicit ev1:Len[T,J], ev2: (J + `1`) as I) = new Len[H::T,I] {
def apply(o: H::T):Int = ev1(o.tail) + 1
}
}
trait ToTuple[X,Z <: Product] {
type In = X
type Out = Z
def apply(o:X):Z
}
trait ToHList[X,Z <: HList] {
type In = X
type Out = Z
def apply(o:X):Z
}
class MapCurried[A <: HList,F[_,_]](val raw:A) extends AnyVal {
def apply[B <: HList](f:Any => Any)(implicit map:HLMap[F,A,B]):B = map(f, raw)
}
implicit class HListOps[A <: HList](val raw:A) extends AnyVal {
def ::[B](e:B) = new `::`(e, raw)
def tuple[B <: Product](implicit ev:A ToTuple B):B = ev(raw)
def reverse[Z <: HList](implicit reverse:Reverse[A,`[]`,Z]):Z = reverse(raw, `[]`)
def ++ [B <: HList,Z <: HList](b:B)(implicit append:Append[A,B,Z]):Z = append(raw, b)
def tail[B <: HList](implicit tail:Tail[A,B]):B = tail(raw)
def head[B](implicit head:Head[A,B]):B = head(raw)
def last[B](implicit last:Last[A,B]):B = last(raw)
def take[N <: Num](implicit f:Take[A,N,_ <: HList]):f.Out = f(raw).asInstanceOf[f.Out] // explicit casting for IDEA
def drop[N <: Num](implicit f:Drop[A,N,_ <: HList]):f.Out = f(raw).asInstanceOf[f.Out] // explicit casting for IDEA
def size(implicit len:Len[A,_]) = len(raw)
def map[F[_,_]]:MapCurried[A,F] = new MapCurried(raw)
def zip[B <: HList,Z <: HList](b:B)(implicit zip:Zip[A,B,Z]):Z = zip(raw, b)
}
implicit class TupleOps[A <: Product](val raw:A) extends AnyVal {
def hlist[B <: HList](implicit ev:A ToHList B):B = ev(raw)
def inverse[B <: HList,C <: HList,D <: Product]
(implicit ev1: A ToHList B, ev2:Reverse[B,`[]`,C], ev3: C ToTuple D):D = ev3(ev2(ev1(raw), `[]`))
def :+ [B,C <: HList,D <: HList,E <: Product]
(rhs:B)(implicit ev1: A ToHList C, ev2:Append[C,B::`[]`,D], ev3: D ToTuple E):E = ev3(ev1(raw) ++ (rhs::`[]`))
def +: [B,C <: HList,D <: HList,E <: Product]
(lhs:B)(implicit ev1: A ToHList C, ev2:Append[B::`[]`,C,D], ev3: D ToTuple E):E = ev3((lhs::`[]`) ++ ev1(raw))
def _n[B <: HList,C <: HList,D <: Product]
(implicit ev1: A ToHList B, ev2:Last[B,C], ev3: C ToTuple D):D = ev3(ev1(raw).last)
def rshift[X <: HList,B <: HList,C <: Product]
(implicit ev1: A ToHList X, wt1: X <:< (Any::B), ev2: B ToTuple C):C = ev2(wt1(ev1(raw)).tail)
def lshift[X <: HList,B <: HList,C <: HList,D <:HList,E <: Product]
(implicit
ev1: A ToHList B
, ev2:Reverse[B,`[]`,X], wt1: X <:< (Any::C)
, ev3:Reverse[C,`[]`,D]
, ev4: D ToTuple E):E = ev4(wt1(ev1(raw).reverse).tail.reverse)
}
implicit def tuple1[A] = new ToTuple[A::`[]`.type,Tuple1[A]] {
def apply(z:In):Out = z match { case a::_ => Tuple1(a) }
}
implicit def hlist1[A] = new ToHList[Tuple1[A],A::`[]`] {
def apply(z:In):Out = z._1::`[]`
}
if (false) (2 to 22).foreach { i =>
print(
"""
|implicit def tuple<#>[<A,>] = new ToTuple[<A::>::`[]`,(<A,>)] {
| def apply(z:In):Out = z match { case <a::>::`[]` => (<a,>) }
|}
""".stripMargin
.replace( "<#>", i + "")
.replace( "<A,>", (0 until i).map('A' + _ toChar).mkString( ","))
.replace( "<a,>", (0 until i).map('a' + _ toChar).mkString( ","))
.replace("<A::>", (0 until i).map('A' + _ toChar).mkString("::"))
.replace("<a::>", (0 until i).map('a' + _ toChar).mkString("::")))
}
implicit def tuple2[A,B] = new ToTuple[A::B::`[]`,(A,B)] {
def apply(z:In):Out = z match { case a::b::`[]` => (a,b) }
}
implicit def tuple3[A,B,C] = new ToTuple[A::B::C::`[]`,(A,B,C)] {
def apply(z:In):Out = z match { case a::b::c::`[]` => (a,b,c) }
}
implicit def tuple4[A,B,C,D] = new ToTuple[A::B::C::D::`[]`,(A,B,C,D)] {
def apply(z:In):Out = z match { case a::b::c::d::`[]` => (a,b,c,d) }
}
implicit def tuple5[A,B,C,D,E] = new ToTuple[A::B::C::D::E::`[]`,(A,B,C,D,E)] {
def apply(z:In):Out = z match { case a::b::c::d::e::`[]` => (a,b,c,d,e) }
}
implicit def tuple6[A,B,C,D,E,F] = new ToTuple[A::B::C::D::E::F::`[]`,(A,B,C,D,E,F)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::`[]` => (a,b,c,d,e,f) }
}
implicit def tuple7[A,B,C,D,E,F,G] = new ToTuple[A::B::C::D::E::F::G::`[]`,(A,B,C,D,E,F,G)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::`[]` => (a,b,c,d,e,f,g) }
}
implicit def tuple8[A,B,C,D,E,F,G,H] = new ToTuple[A::B::C::D::E::F::G::H::`[]`,(A,B,C,D,E,F,G,H)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::`[]` => (a,b,c,d,e,f,g,h) }
}
implicit def tuple9[A,B,C,D,E,F,G,H,I] = new ToTuple[A::B::C::D::E::F::G::H::I::`[]`,(A,B,C,D,E,F,G,H,I)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::`[]` => (a,b,c,d,e,f,g,h,i) }
}
implicit def tuple10[A,B,C,D,E,F,G,H,I,J] = new ToTuple[A::B::C::D::E::F::G::H::I::J::`[]`,(A,B,C,D,E,F,G,H,I,J)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::`[]` => (a,b,c,d,e,f,g,h,i,j) }
}
implicit def tuple11[A,B,C,D,E,F,G,H,I,J,K] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::`[]`,(A,B,C,D,E,F,G,H,I,J,K)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::`[]` => (a,b,c,d,e,f,g,h,i,j,k) }
}
implicit def tuple12[A,B,C,D,E,F,G,H,I,J,K,L] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l) }
}
implicit def tuple13[A,B,C,D,E,F,G,H,I,J,K,L,M] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m) }
}
implicit def tuple14[A,B,C,D,E,F,G,H,I,J,K,L,M,N] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::N::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M,N)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::n::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m,n) }
}
implicit def tuple15[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::n::o::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) }
}
implicit def tuple16[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::n::o::p::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) }
}
implicit def tuple17[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::n::o::p::q::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) }
}
implicit def tuple18[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::n::o::p::q::r::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) }
}
implicit def tuple19[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::S::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::n::o::p::q::r::s::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s) }
}
implicit def tuple20[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::S::T::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::n::o::p::q::r::s::t::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t) }
}
implicit def tuple21[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::S::T::U::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::n::o::p::q::r::s::t::u::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u) }
}
implicit def tuple22[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V] = new ToTuple[A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::S::T::U::V::`[]`,(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V)] {
def apply(z:In):Out = z match { case a::b::c::d::e::f::g::h::i::j::k::l::m::n::o::p::q::r::s::t::u::v::`[]` => (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v) }
}
if (false) (2 to 22).foreach { i =>
print(
"""
|implicit def hlist<#>[<,>] = new ToHList[(<,>),<A::>::`[]`] {
| def apply(z:In):Out = <_::>::`[]`
|}
""".stripMargin
.replace( "<#>", i + "")
.replace( "<,>", (0 until i).map('A' + _ toChar).mkString( ","))
.replace("<A::>", (0 until i).map('A' + _ toChar).mkString("::"))
.replace("<_::>", (1 to i).map("z._" + _).mkString("::")))
}
implicit def hlist2[A,B] = new ToHList[(A,B),A::B::`[]`] {
def apply(z:In):Out = z._1::z._2::`[]`
}
implicit def hlist3[A,B,C] = new ToHList[(A,B,C),A::B::C::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::`[]`
}
implicit def hlist4[A,B,C,D] = new ToHList[(A,B,C,D),A::B::C::D::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::`[]`
}
implicit def hlist5[A,B,C,D,E] = new ToHList[(A,B,C,D,E),A::B::C::D::E::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::`[]`
}
implicit def hlist6[A,B,C,D,E,F] = new ToHList[(A,B,C,D,E,F),A::B::C::D::E::F::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::`[]`
}
implicit def hlist7[A,B,C,D,E,F,G] = new ToHList[(A,B,C,D,E,F,G),A::B::C::D::E::F::G::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::`[]`
}
implicit def hlist8[A,B,C,D,E,F,G,H] = new ToHList[(A,B,C,D,E,F,G,H),A::B::C::D::E::F::G::H::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::`[]`
}
implicit def hlist9[A,B,C,D,E,F,G,H,I] = new ToHList[(A,B,C,D,E,F,G,H,I),A::B::C::D::E::F::G::H::I::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::`[]`
}
implicit def hlist10[A,B,C,D,E,F,G,H,I,J] = new ToHList[(A,B,C,D,E,F,G,H,I,J),A::B::C::D::E::F::G::H::I::J::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::`[]`
}
implicit def hlist11[A,B,C,D,E,F,G,H,I,J,K] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K),A::B::C::D::E::F::G::H::I::J::K::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::`[]`
}
implicit def hlist12[A,B,C,D,E,F,G,H,I,J,K,L] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L),A::B::C::D::E::F::G::H::I::J::K::L::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::`[]`
}
implicit def hlist13[A,B,C,D,E,F,G,H,I,J,K,L,M] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M),A::B::C::D::E::F::G::H::I::J::K::L::M::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::`[]`
}
implicit def hlist14[A,B,C,D,E,F,G,H,I,J,K,L,M,N] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M,N),A::B::C::D::E::F::G::H::I::J::K::L::M::N::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::z._14::`[]`
}
implicit def hlist15[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O),A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::z._14::z._15::`[]`
}
implicit def hlist16[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P),A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::z._14::z._15::z._16::`[]`
}
implicit def hlist17[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q),A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::z._14::z._15::z._16::z._17::`[]`
}
implicit def hlist18[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R),A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::z._14::z._15::z._16::z._17::z._18::`[]`
}
implicit def hlist19[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S),A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::S::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::z._14::z._15::z._16::z._17::z._18::z._19::`[]`
}
implicit def hlist20[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T),A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::S::T::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::z._14::z._15::z._16::z._17::z._18::z._19::z._20::`[]`
}
implicit def hlist21[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U),A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::S::T::U::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::z._14::z._15::z._16::z._17::z._18::z._19::z._20::z._21::`[]`
}
implicit def hlist22[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V] = new ToHList[(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V),A::B::C::D::E::F::G::H::I::J::K::L::M::N::O::P::Q::R::S::T::U::V::`[]`] {
def apply(z:In):Out = z._1::z._2::z._3::z._4::z._5::z._6::z._7::z._8::z._9::z._10::z._11::z._12::z._13::z._14::z._15::z._16::z._17::z._18::z._19::z._20::z._21::z._22::`[]`
}
}
package jp.segfault.optparsec
object N {
trait Expr
abstract class Num(val raw:Int) extends Expr
object `0` extends Num(0)
case class s[E](n:Int) extends Num(n)
if (false) (1 to 22).foreach { i =>
println(
"""
|type `<i>` = s[`<j>`]
""".stripMargin.trim
.replace("<i>", ""+ (i))
.replace("<j>", ""+ (i - 1)))
}
type `0` = `0`.type
type `1` = s[`0`]
type `2` = s[`1`]
type `3` = s[`2`]
type `4` = s[`3`]
type `5` = s[`4`]
type `6` = s[`5`]
type `7` = s[`6`]
type `8` = s[`7`]
type `9` = s[`8`]
type `10` = s[`9`]
type `11` = s[`10`]
type `12` = s[`11`]
type `13` = s[`12`]
type `14` = s[`13`]
type `15` = s[`14`]
type `16` = s[`15`]
type `17` = s[`16`]
type `18` = s[`17`]
type `19` = s[`18`]
type `20` = s[`19`]
type `21` = s[`20`]
type `22` = s[`21`]
trait #+# [A <: Num,B <: Num,Z <: Num] {
type Out = Z
def apply(a:A, b:B):Z
}
object #+# {
implicit def case0[A <: Num,Z <: Num] = new #+# [A,`0`,A]() {
def apply(a:A, b:`0`):A = a
}
implicit def case1[A <: Num,B <: Num,Z <: Num]
(implicit add: #+#[A,B,Z]) = new #+# [A,s[B],s[Z]]() {
def apply(a:A, b:s[B]):s[Z] = s[Z](a.raw + b.raw)
}
}
trait #*# [A <: Num,B <: Num,Z <: Num] {
type Out = Z
def apply(a:A, b:B):Z
}
object #*# {
implicit def case0[A <: Num] = new #*# [`0`,`0`,`0`]() {
def apply(a:`0`, b:`0`):`0` = `0`
}
implicit def case1[A <: Num] = new #*# [s[A],`0`,`0`]() {
def apply(a:s[A], b:`0`):`0` = `0`
}
implicit def case2[B <: Num] = new #*# [`0`,s[B],`0`]() {
def apply(a:`0`, b:s[B]):`0` = `0`
}
implicit def case3[A <: Num,B <: Num,Y <: Num,Z <: Num]
(implicit mul: #*#[s[A],B,Y], add: #+#[Y,s[A],s[Z]]) = new #*# [s[A],s[B],s[Z]]() {
def apply(a:s[A], b:s[B]):s[Z] = s[Z](a.raw * b.raw)
}
implicit def case4[A <: Num,B <: Num,Y <: Num,Z <: Num]
(implicit add: #+#[s[A],Y,s[Z]], mul: #*#[s[A],B,Y]) = new #*# [s[A],s[B],s[Z]]() {
def apply(a:s[A], b:s[B]):s[Z] = s[Z](a.raw * b.raw)
}
}
trait + [A <: Expr,B <: Expr] extends Expr
trait - [A <: Expr,B <: Expr] extends Expr
trait * [A <: Expr,B <: Expr] extends Expr
trait / [A <: Expr,B <: Expr] extends Expr
trait as[E <: Expr,Z <: Num]
object as {
implicit def id[N <: Num] = new as[N,N]() {}
implicit def + [N <: Num
,A <: Expr, A2 <: Num
,B <: Expr, B2 <: Num]
(implicit as1: A as A2, as2: B as B2, add: #+#[A2,B2,N]) = new as[A `+` B,N]() {
}
implicit def - [N <: Num
,A <: Expr, A2 <: Num
,B <: Expr, B2 <: Num]
(implicit as1: A as A2, as2: B as B2, add: #+#[B2,N,A2]) = new as[A `-` B,N]() {
}
implicit def * [N <: Num
,A <: Expr, A2 <: Num
,B <: Expr, B2 <: Num]
(implicit as1: A as A2, as2: B as B2, mul: #*#[A2,B2,N]) = new as[*[A, B],N]() {
}
implicit def / [N <: Num
,A <: Expr, A2 <: Num
,B <: Expr, B2 <: Num]
(implicit as1: A as A2, as2: B as B2, mul: #*#[B2,N,A2]) = new as[A `/` B,N]() {
}
}
trait < [A <: Num,B <: Num]
object < {
implicit def case0[X <: Num] = new < [`0`,s[X]] {}
implicit def case1[A <: Num,B <: Num](implicit ev1: A < B) = new < [s[A],s[B]] {}
}
// low priority implicits for Eq
trait Eq0 {
implicit def case0[A,B] = new Eq[A,B,`0`] {}
}
trait Eq[A,B,C]
object Eq extends Eq0 {
implicit def case1[A] = new Eq[A,A,`1`] {}
}
trait =/=[A,B]
object =/= {
implicit def case0[A,B,C](implicit eq:Eq[A,B,C], wt: C =:= `0`) = new =/=[A,B] {}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment