I've finally decided to complete the remaining exercises in
Seven Languages in Seven Weeks, the last of which is "Implement a Monad in a nonfunctional language." So I implemented four of them. In Julia. And wrote a macro so you can use Haskell's do-syntax (with minor differences).
Here's the source:
https://gist.github.com/3677645And you can do silly things like:
julia> @mdo begin
a <- Maybe(1)
b <- Maybe(2)
return a + 2*b
end
Maybe(5)
julia> @mdo begin
a <- Maybe(1)
b <- Maybe(nothing)
return a + 2*b
end
Maybe(nothing)
or:
julia> @mdo begin
a <- MList(1:3)
b <- MList(4:6)
return (a,b)
end
MList([(1,4), (1,5), (1,6), (2,4), (2,5), (2,6), (3,4), (3,5), (3,6)])(seriously, just use a list comprehension!)
There are also implementations of
Identity and
State. So, uh, have fun?
If you look at the source, I've commented out all the module bits. It turns out that I hit interesting scoping problems if you use the modularized version:
julia> @mdo begin
y <- @mdo begin
x <- Identity(5)
return x+1
end
return y + 1
end
x not defined
julia> mtest(m) = @mdo begin
x <- m
y <- Identity(x+1)
return y + 1
end
julia> mtest(Identity(5))
in mtest: m not defined
in mtest at none:51
So I've no idea how to sort that out. Spelled out explicitly, it works as expected:
julia> bind(bind(Identity(5)) do x
mreturn(Identity, x+1)
end) do y
mreturn(Identity, y+1)
end
Identity(7)At any rate, I hope someone finds this interesting. Ideas for improvements are certainly welcome too!