At my second year of university i made a project for the “Programming Languages” course. It consisted in a simple program written in Haskell to eliminate a Monad from the code.
It exactly rewrites another piece of haskell code containing the definition of one single monad, and rewrites it without it.
The monad must be user defined, it is no possible to remove the IO monad for instance.
A current limitation is the monad must be defined in the file to rewrite, not that is a big limitation thought.
But an example is better then words…
This code uses a list as state, and gives the user 2 functions, insertList to insert a list, and getElement to get an element from the list.
data Test a = Test (TestS -> (a,TestS))
instance Monad Test where
return a = Test (\s -> (a,s))
Test f >>= gm = Test (\s0 -> let (x,s1) = f s0
(Test g) = gm x
in g s1)
insertList l = Test (\s0 -> ((),l))
getElement n = Test (\(l) -> (l!!n,l))
runTest :: TestS -> Test a -> a
runTest s0 (Test c) = fst $ c s0
testcode = do h <- getElement 5
p <- getElement 4
t <- getElement 2
return p
test = runTest [0..] testcode
Then, after passing it to the DeMonadizer
ghc --make Main.hs DeMonad.hs
./Make test.hs
the code looks like this (it’s ugly, i know)
module Test where
type TestS = [Int]
data Test a = Test (TestS -> (a, TestS))
insertList l = Test (\ s0 -> ((), l))
getElement n = Test (\ (l) -> (l !! n, l))
runTest :: TestS -> Test a -> a
runTest s0 (Test c) = fst $ c s0
testcode
= (\ (Test f) ->
Test
(\ s0 ->
let (x, s1) = f s0
(Test g)
= (\ h ->
(\ (Test f) ->
Test
(\ s0 ->
let (x, s1) = f s0
(Test g)
= (\ p ->
(\ (Test f) ->
Test
(\ s0 ->
let (x, s1) = f s0
(Test g) = (\ t -> Test (\ s -> (p, s))) x
in g s1))
(getElement 2))
x
in g s1))
(getElement 4))
x
in g s1))
(getElement 5)
test = runTest [0 ..] testcode
As you can see the monad definition is gone, and with it also the do syntax.
This solution allowed some haskell code to run as curry code!
It is very similar in syntax, but it is a funcional-logic programming language, and as such it has non-determinism (and everybody should love the magic of =:=). The code is rather long, since it must provide the language with actions for each of his syntactical elements, it can be found at his code page.
Posted by Dario Meloni