Discussion:
Combining monadic behaviors
(too old to reply)
luserdroog
2019-09-16 00:01:37 UTC
Permalink
I've been watching Philip Wadler videos over and over again to get a handle
on monads. But a question has arisen that I can't find an easy answer to.
Is there in general an easy way to combine multiple monads together?
Say I want both State *and* Output and I have a monad that produces output,
can I add State transformations to it or do I have to rewrite the whole
program?

The specific case is I'm working with hand-written parser combinators
in PostScript that are modeled after the excellent paper by Graham and Hutton.

I'm trying to use these parsers to make a scanner for PostScript syntax.
At the top level I have handlers attached which produce an array of
[ original-string ps-object ] pairs. eg.

/ps-token
//rad-integer { cvi } handle
//real { cvr } handle plus
//integer { cvi } handle plus
//name { cvn cvx } handle plus
(/) char //name seq { rest cvn } handle plus
(/) char (/) char seq //name seq
{ rest rest cvn
dup {load}stopped not{ exch pop }if } handle plus
//ps-string { 1 1 index length 2 sub getinterval
} handle plus
//delimiter { cvn cvx } handle plus
def

But a complication arises when dealing with escapes in strings.
I can't eliminate the backslash character at the point where it's
found because the outer level code needs the original string
intact to advance its pointer in the input string.

So my options seem to be: add an extra pass to clean up string
data later, or augment the whole system to carry the input
position State around.

If there's some theoretical way to do it, I'd love to augment
my parser monad with State without rewriting the whole program.

Any thoughts or pointers appreciated.

https://github.com/luser-dr00g/pcomb/blob/master/ps/pc9token.ps
Mark Carroll
2019-09-16 07:27:01 UTC
Permalink
Post by luserdroog
I've been watching Philip Wadler videos over and over again to get a handle
on monads. But a question has arisen that I can't find an easy answer to.
Is there in general an easy way to combine multiple monads together?
https://wiki.haskell.org/Lifting#Monad_lifting - "lifting" is the term
in Haskell for combining monads. Then one becomes the "inner" one and
the other the "outer" one. There's some broader discussion at
https://mmhaskell.com/blog/2017/3/6/making-sense-of-multiple-monads
I'd guess that some analogy of the approach may work for you but it's
too early on a Monday morning for me to be able to say more than that!

-- Mark
luserdroog
2019-09-21 08:04:14 UTC
Permalink
Post by Mark Carroll
Post by luserdroog
I've been watching Philip Wadler videos over and over again to get a handle
on monads. But a question has arisen that I can't find an easy answer to.
Is there in general an easy way to combine multiple monads together?
https://wiki.haskell.org/Lifting#Monad_lifting - "lifting" is the term
in Haskell for combining monads. Then one becomes the "inner" one and
the other the "outer" one. There's some broader discussion at
https://mmhaskell.com/blog/2017/3/6/making-sense-of-multiple-monads
I'd guess that some analogy of the approach may work for you but it's
too early on a Monday morning for me to be able to say more than that!
-- Mark
TY Knowing what to search for led me to this, which is a little more on
my level.

https://medium.com/javascript-scene/javascript-monads-made-simple-7856be57bfe8
Maciek Godek
2020-02-04 16:25:46 UTC
Permalink
Post by luserdroog
I've been watching Philip Wadler videos over and over again to get a handle
on monads. But a question has arisen that I can't find an easy answer to.
Is there in general an easy way to combine multiple monads together?
Say I want both State *and* Output and I have a monad that produces output,
can I add State transformations to it or do I have to rewrite the whole
program?
There is a thing called "monad transformers", which was invented specifically for this purpose. I think that this is a fairly accessible introduction (if you're capable of digesting Scala):



There is a broad area of research on "effect systems", which are meant to combine the capabilities of different monads, but they are generally based on the idea of "free monads" (where "free" means "uninterpreted" -- this technique seems to be very popular in Scala, so it's easy to find videos on youtube)
Loading...