package michid.meta
import michid.meta.Naturals._
object PreProc {
def LOOP[N] = null.asInstanceOf[N]
trait Loop[N] {
def apply(block: => Unit)
}
implicit def loop0(n: ZERO) = new Loop[ZERO] {
def apply(block: => Unit) { }
}
implicit def loop[N <: NAT](n: SUCC[N])(implicit f: N => Loop[N]) = new Loop[SUCC[N]] {
def apply(block: => Unit) {
block
null.asInstanceOf[N].apply(block)
}
}
}
object LoopUnroll {
import PreProc._
def unrollTest() {
// Need -Yrecursion 1
//LOOP[(_3 x _2)#v] {
LOOP[_5] {
println("hello world")
}
}
def main(args: Array[String]) {
unrollTest()
}
}
package michid.meta
object Naturals {
trait NAT {
type a[s[_ <: NAT] <: NAT, z <: NAT] <: NAT
type v = a[SUCC, ZERO]
}
final class ZERO extends NAT {
type a[s[_ <: NAT] <: NAT, z <: NAT] = z
}
final class SUCC[n <: NAT] extends NAT {
type a[s[_ <: NAT] <: NAT, z <: NAT] = s[n#a[s, z]]
}
type _0 = ZERO
type _1 = SUCC[_0]
type _2 = SUCC[_1]
type _3 = SUCC[_2]
type _4 = SUCC[_3]
type _5 = SUCC[_4]
type _6 = SUCC[_5]
trait ADD[n <: NAT, m <: NAT] extends NAT {
type a[s[_ <: NAT] <: NAT, z <: NAT] = n#a[s, m#a[s, z]]
}
trait MUL[n <: NAT, m <: NAT] extends NAT {
trait curry[n[_[_], _], s[_]] { type f[z] = n[s, z] }
type a[s[_ <: NAT] <: NAT, z <: NAT] = n#a[curry[m#a, s]#f, z]
}
type +[n <: NAT, m <: NAT] = ADD[n, m]
type x[n <: NAT, m <: NAT] = MUL[n, m]
}