-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b8a23e9
commit f1bb72f
Showing
2 changed files
with
98 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ i9999.scala | |
12093.scala | ||
9757.scala | ||
9890.scala | ||
13491.scala | ||
|
||
# Opaque type | ||
i5720.scala | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import scala.annotation.unchecked.uncheckedVariance | ||
|
||
import scala.language.implicitConversions | ||
|
||
sealed trait HList extends Product with Serializable | ||
final case class ::[+H, +T <: HList](head: H, tail: T) extends HList | ||
|
||
sealed trait HNil extends HList | ||
case object HNil extends HNil | ||
|
||
trait HListable[T] { | ||
type Out <: HList | ||
} | ||
|
||
object HListable { | ||
type HL0[T] <: HList = T match { | ||
case Unit => HNil | ||
case HNil => HNil | ||
case ::[a, b] => ::[a, b] | ||
case _ => T :: HNil | ||
} | ||
|
||
implicit def calc[T]: HListable[T] { type Out = HL0[T] } = ??? | ||
} | ||
|
||
sealed trait TailSwitch[L <: HList, T <: HList, R <: HList] { | ||
type Out <: HList | ||
} | ||
object TailSwitch { | ||
type Reverse0[Acc <: HList, L <: HList] <: HList = L match { | ||
case HNil => Acc | ||
case ::[h, t] => Reverse0[h :: Acc, t] | ||
} | ||
|
||
type Reverse1[L <: HList] <: HList = L match { | ||
case HNil => HNil | ||
case ::[h, t] => Reverse0[h :: HNil, t] | ||
} | ||
|
||
type Prepend0[A <: HList, B <: HList] <: HList = A match { | ||
case HNil => B | ||
case ::[h, t] => ::[h, Prepend0[t, B]] | ||
} | ||
|
||
// type-level implementation of this algorithm: | ||
// @tailrec def rec(L, LI, T, TI, R, RI) = | ||
// if (TI <: L) R | ||
// else if (LI <: T) RI.reverse ::: R | ||
// else if (LI <: HNil) rec(L, HNil, T, TI.tail, R, RI) | ||
// else if (TI <: HNil) rec(L, LI.tail, T, HNil, R, LI.head :: RI) | ||
// else rec(L, LI.tail, T, TI.tail, R, LI.head :: RI) | ||
// rec(L, L, T, T, R, HNil) | ||
type TailSwitch0[L <: HList, LI <: HList, T <: HList, TI <: HList, R <: HList, RI <: HList] <: HList = TI match { | ||
case L => R | ||
case _ => | ||
LI match { | ||
case T => Prepend0[Reverse1[RI], R] | ||
case HNil => | ||
TI match { | ||
case ::[_, t] => TailSwitch0[L, HNil, T, t, R, RI] | ||
} | ||
case ::[h, t] => | ||
TI match { | ||
case HNil => TailSwitch0[L, t, T, HNil, R, h :: RI] | ||
case ::[_, tt] => TailSwitch0[L, t, T, tt, R, h :: RI] | ||
} | ||
} | ||
} | ||
|
||
type Aux[L <: HList, LI <: HList, T <: HList, TI <: HList, R <: HList, RI <: HList, Out <: HList] = | ||
TailSwitch[L, T, R] { type Out = TailSwitch0[L, L, T, T, R, HNil] } | ||
|
||
implicit def tailSwitch[L <: HList, T <: HList, R <: HList] | ||
: TailSwitch[L, T, R] { type Out = TailSwitch0[L, L, T, T, R, HNil] } = ??? | ||
} | ||
|
||
sealed class Rule[-I <: HList, +O <: HList] { | ||
def ~[I2 <: HList, O2 <: HList](that: Rule[I2, O2])(implicit | ||
i: TailSwitch[I2, O@uncheckedVariance, I@uncheckedVariance], | ||
o: TailSwitch[O@uncheckedVariance, I2, O2] | ||
): Rule[i.Out, o.Out] = ??? | ||
|
||
} | ||
object Rule { | ||
type Rule0 = Rule[HNil, HNil] | ||
type RuleN[+L <: HList] = Rule[HNil, L] | ||
|
||
def rule[I <: HList, O <: HList](r: Rule[I, O]): Rule[I, O] = ??? | ||
implicit def valueMap[T](m: Map[String, T])(implicit h: HListable[T]): RuleN[h.Out] = ??? | ||
} | ||
|
||
object Test { | ||
import Rule._ | ||
val colors: Map[String, Int] = Map("red" -> 1, "green" -> 2, "blue" -> 3) | ||
def EOI: Rule0= ??? | ||
val r = rule(colors ~ EOI) | ||
} |