Skip to content

Instantly share code, notes, and snippets.

@jrudolph
Created February 19, 2009 13:51
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save jrudolph/66925 to your computer and use it in GitHub Desktop.
Save jrudolph/66925 to your computer and use it in GitHub Desktop.
Scala-Metaprogramming: Towers of Hanoi
/*
* This is the Towers of Hanoi example from the prolog tutorial [1]
* converted into Scala, using implicits to unfold the algorithm at
* compile-time.
*
* [1] http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_3.html
*/
object TowersOfHanoi {
import scala.reflect.Manifest
def simpleName(m:Manifest[_]):String = {
val name = m.toString
name.substring(name.lastIndexOf('$')+1)
}
trait Nat
final class _0 extends Nat
final class Succ[Pre<:Nat] extends Nat
type _1 = Succ[_0]
type _2 = Succ[_1]
type _3 = Succ[_2]
type _4 = Succ[_3]
case class Move[N<:Nat,A,B,C]()
implicit def move0[A,B,C](implicit a:Manifest[A],b:Manifest[B]):Move[_0,A,B,C] = {
System.out.println("Move from "+simpleName(a)+" to "+simpleName(b));null
}
implicit def moveN[P<:Nat,A,B,C](implicit m1:Move[P,A,C,B],m2:Move[_0,A,B,C],m3:Move[P,C,B,A])
:Move[Succ[P],A,B,C] = null
def run[N<:Nat,A,B,C](implicit m:Move[N,A,B,C]) = null
case class Left()
case class Center()
case class Right()
def main(args:Array[String]){
run[_2,Left,Right,Center]
}
}
@HusrevAtSky
Copy link

HusrevAtSky commented Feb 26, 2018

Using shapeless I created a version which moves the result to the type.
It obviously ruins the 'self-contained'ness of the gist, but here it is: https://gist.github.com/HusrevAtSky/cae020c79c844e22024c8cd027a5c6ce

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment