16 November 2009

Typefuck

Ah, so lovely to see you again, gentle readers. It's been a long time - and I have no explanations for my absence - but you must forgive me - after all, long does the mind dwell on mysteries, and long can mysteries dwell unseen.

But worry not, gentle readers, for I have a gift for you. As you know I have a fondness for implementing programming languages - it makes me think of kittens, polymorphic types and lockers full of stolen credit cards.

Enough to bring a nostalgic tear to anyone's eye.

Especially those who value esoteric knowledge.

Secrets await you, fair soul, who may read this code and wonder how much I had to drink.

Brainfuck implemented within the Haskell type checker

WTF:
Typefuck is a brainfuck which runs within the Haskell type checker - that is, prior to compilation. If a rationale is to be sought, it is as another proof that the GHC type checker is turing complete.

Here are the type level commands

-- | Add +
data A = A
deriving Show

-- | Minus -
data M = M
deriving Show

-- | Right >
data R = R
deriving Show

-- | Left <
data L = L
deriving Show

-- | Iterate [ ]
data I bf = I bf
deriving Show

-- | Put .
data P = P
deriving Show

-- | Get ,
data G = G
deriving Show

So the simple brainfuck program: ,>,[-<+>]<.
(which adds two numbers)

is equivalent to the Haskell type

type Add =
   Cons G
   (Cons R
   (Cons G
   (Cons (I (Cons M
            (Cons L
            (Cons A
            (Cons R Nil)))))
   (Cons L
   (Cons P Nil
   )))))


Use the Brainfuck type to evaluate.

The first type parameter represents the program, while the second represents the input.

Input and output are represented as Cons-ed linked lists of unary integers, constructed from Succ, Zero, and Neg (for negative integers)

Assert that the function 'show_type' has this type to show a value level solution for the problem (though all working is done within the type checker)

Example:

spoon@utensil:~/Desktop$ ghci
GHCi, version 6.10.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> :m +Typefuck
Prelude Typefuck> show_type :: Brainfuck Add (Cons (Succ (Succ (Succ Zero))) (Cons (Succ (Succ Zero)) Nil))
Loading package syb ... linking ... done.
Loading package base-3.0.3.1 ... linking ... done.
Loading package typefuck-0.0.1 ... linking ... done.
Cons (Succ (Succ (Succ (Succ (Succ Zero))))) Nil

5 comments:

  1. johnny, you are too smart for my own good.

    L

    ReplyDelete
  2. great :)
    i'd have renamed Cons to ::: though (or some other operator) to make it look a bit nicer.

    ReplyDelete
  3. This is awesome, and I would love more explanation on how it works.

    Unfortunately in playing with it, I get an error when trying your example:

    Prelude> :m + Typefuck
    Prelude Typefuck> show_type :: Brainfuck Add (Cons (Succ (Succ (Succ Zero))) (Cons (Succ (Succ Zero)) Nil))

    No instance for (Show
    (Brainfuck
    Add
    (Cons (Succ (Succ (Succ Zero))) (Cons (Succ (Succ Zero)) Nil))))
    arising from a use of `print' at


    Possible fix:
    add an instance declaration for
    (Show
    (Brainfuck
    Add
    (Cons (Succ (Succ (Succ Zero))) (Cons (Succ (Succ Zero)) Nil))))
    In the expression: print it
    In a 'do' expression: print it

    The contents of the tarball named v0.1 is actually Typefuck 0.2. Maybe that has something to do with it.

    ReplyDelete
  4. > The contents of the tarball named v0.1 is actually Typefuck 0.2

    I just symlinked the old tarball to the new version because I was too lazy to change the link.

    I guess that's pretty odd and confusing behaviour so I've changed the old link to point to the new one.

    So the bug - unfortunately I can't replicate this with the 0.0.2 version of typefuck!

    What version of GHC are you using?
    Also what is the output of 'ghc-pkg describe typefuck'?

    ReplyDelete
  5. The problem I think is with my GHC 6.8 and it's fake support for type families. Sorry! meant to post that followup.

    ReplyDelete