Meta-Programming with Scala: Multiplication

This is the code for the blog entry Meta-Programming with Scala Part III: Partial function application

package michid.meta

object Metamult {
    // Church encoding of natural numbers
    type _0[s[_], z] = z
    type _1[s[_], z] = s[z]
    type _2[s[_], z] = s[s[z]]
    type _3[s[_], z] = s[s[s[z]]]

    trait curry[n[_[_], _], s[_]] {
      type f[z] = n[s, z]
    }

    // Multiplication for this encoding
    type mult[m[_[_], _], n[_[_], _], s[_], z] = m[curry[n, s]#f, z]

    abstract class Zero
    abstract class Succ[T]

    // Use of infix notation for more convinient syntax
    type x[m[_[_], _], n[_[_], _]] = mult[m, n, Succ, Zero]


    // See https://michid.wordpress.com/2008/03/12/puzzle-the-depth-of-a-type-solution/
    def value[T] = null.asInstanceOf[T];

    trait Rep[T] {
        def eval: Int
    }

    implicit def toRep0(n: Zero) = new Rep[Zero] {
        def eval = 0
    }

    implicit def toRepN[T](n: Succ[T])(implicit f: T => Rep[T]) = new Rep[Succ[T]] {
        def eval = f(value[T]).eval + 1
    }

    def main(args: Array[String]) {
        println((value[_1 x _1]).eval) // prints 1
        println((value[_1 x _2]).eval) // prints 2
        println((value[_2 x _1]).eval) // prints 2
        println((value[_2 x _2]).eval) // prints 4
        println((value[_2 x _3]).eval) // prints 6
        println((value[_3 x _2]).eval) // prints 6
        println((value[_3 x _3]).eval) // prints 9
    }

}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: