Here’s a question that came up while I’ve been trying to

href="http://greenokapi.net/blog/2009/05/04/currying-in-perl/">implement

currying in Perl: is Currying monadic?

I’ve tried a couple of times, but not managed to explain what I mean very well on #haskell, so let’s

see if a longer writeup explains it better.

My simplistic understanding of monads is that they take various things that

are nests of nested expressions, and allow you to reason about them, and

given them a pretty syntax that makes it look like they are in fact a

sequence of commands.

For example: (pseudocode)

let a = 1 let b = 2 output a+b

Looks like a sequence of commands, but you couldn’t just separate each

line and string the commands together. Rather you have to consider it

as a nest:

(let a = 1 (let b = 2 (output a+b )))

And in many cases, we can go from a nested structure to a monad, for example, we could simplify these horribly nested if s:

(if file exists (if file is readable (if reading the file gave a string (if the string matches a username (do some action with the username)))))

… into a nice Maybe monad:

do check file exists check file is readable string

Similarly, nested lists:

(for each i in list 1 (for each j in list 2 (is i the same as j? (output i))))

can be abstracted as a List monad:

do i

OK, so I'm not talking about wrapping and unwrapping values, the monad

laws, or typing in general. They are what gives this stuff its strong

theoretical basis and makes it robust. But the simple-minded "Nest ->

Sequence" idea works for me at least, and gives a good feel for

where monads can come in useful.

Currying

So... when I was implementing currying, I noted that you could write a

currying sub (pseudocode again):

function add3 (a, b, c) { return a+b+c }

as something like this:

function add3 (a) { return function (b) { return function (c) { return a+b+c } } }

This is again a nested expression. So I wondered if you could again "flatten" it with a monadic do block:

let add3 = do a

OK, so I "know" that functions in Haskell (which uses currying for

functions as a general rule) are the "Reader monad". But I don't

understand it well enough to know if that means you can use Reader to

implement the above...

(I don't understand Reader at all in fact. I must bang my head against

it again, but I find it very confusing - how the monad is represented,

what the functions are, and how they get magically applied.)

So, I did attempt to implement it using my Perl module

Acme::Monads . This href="http://github.com/osfameron/acme--monads/blob/master/t/04_curry.t">test

shows that this sort of works:

my $add = mdo (2) { mbind $x = Curry shift; mbind $y = Curry shift; return $x+$y; }; say $add->(1)->(2); # 3, yay!

Note that the "return" isn't a monadic Unit but Perl's return,

i.e. a plain value. That makes this example strictly speaking not

monadic: what I don't know is whether that means the whole idea is fatally flawed, or whether (as I believe) I was just too dumb to fix the errors I got when I tried running with munit...

I suspect that it should be possible, with the

whole expression then being wrapped by some function

( runCurry ?) which extracts the final result out of the monad.

Did this explanation make any sense? Please let me know, and any

comments on whether it's possible/sane to do this (writing currying as a

monad) are appreciated!