-
-
Save HusrevAtSky/cae020c79c844e22024c8cd027a5c6ce to your computer and use it in GitHub Desktop.
Scala-Metaprogramming: Towers of Hanoi
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
import shapeless.ops.hlist.Prepend | |
import shapeless.{::, HList, HNil, Nat, Succ} | |
object Hanoi { | |
// influenced by : https://gist.github.com/jrudolph/66925 | |
// in action : https://youtu.be/mc6c_sX-ESc | |
case class Left() | |
case class Center() | |
case class Right() | |
case class Move[N<:Nat,A,B,C,History <: HList]() | |
implicit def move0[A,B,C]:Move[Nat._1,A,B,C, (A,B) :: HNil] = { | |
null | |
} | |
implicit def moveN[P<:Nat,A,B,C, H1 <: HList, H2 <: HList, H3 <: HList, H2andH3<:HList, Out <: HList] | |
(implicit m1:Move[P,A,C,B, H1], | |
m2:Move[Nat._1,A,B,C,H2], | |
m3:Move[P,C,B,A,H3], | |
prependH2andH3: Prepend.Aux[H2,H3, H2andH3], | |
prepend: Prepend.Aux[H1,H2andH3, Out]) | |
:Move[Succ[P],A,B,C, Out] = null | |
def run[N<:Nat,A,B,C,H <: HList](n: N, a: A, b: B, c: C)(implicit m:Move[N,A,B,C,H]) : H = null.asInstanceOf[H] | |
val a = run(new Nat._3, Left(), Right(), Center()) | |
// type is calculated by intellj as | |
// val a: ::[(Left, Right), HNil] = run(new Nat._1, Left(), Right(), Center()) | |
// val b: ::[(Left, Center), ::[(Left, Right), ::[(Center, Right), HNil]]] = run(new Nat._2, Left(), Right(), Center()) | |
// val c: ::[(Left, Right), ::[(Left, Center), ::[(Right, Center), ::[(Left, Right), ::[(Center, Left), ::[(Center, Right), ::[(Left, Right), HNil]]]]]]] = run(new Nat._3, Left(), Right(), Center()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment