<br><br><div class="gmail_quote">On Sun, Jun 24, 2012 at 2:48 AM, Chris Dornan <span dir="ltr"><<a href="mailto:chris@chrisdornan.com" target="_blank">chris@chrisdornan.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>> > To move between functional and monadic code you have<br>
> > to completely rewrite the code procedurally<br>
<br>
</div><div>> It's false. do-notation is completely optional. It merely makes it<br>
> easier to extract multiple values from monadic actions, instead<br>
> of the basic "one value per step" bind provides. Using join<br>
> and (>>=) is just as easy as do-notation, once you understand the idiom.<br>
<br>
</div>Odersky's point (and mine) was about moving between monadic and functional<br>
code,<br>
not eliminating a do notation (which is indeed a fairly trivial syntactic<br>
device). To take<br>
a fake and absurd example, there is a world of difference between<br>
<br>
add:: Double -> Double-> IO Double<br>
<br>
and the stock addition operator. (Perhaps you need to be very careful about<br>
exceptions.) If you structure your program so that certain kinds of<br>
arithmetic has<br>
to be done monadically then everything that uses these operations must be<br>
written<br>
quite differently from how it would be with simple arithmetic operations.<br></blockquote><div><br></div><div><br></div><div>I sort of see where you're coming from. But I'm having a hard time seeing how this "complaint" would work with respect to Maybe and the other pure monads. In other words, I suspect the problem you're describing is particular to IO and IO-like monads.</div>
<div><br></div><div>If a function isn't total, it is entirely natural to use "Maybe" to encapsulate the potential for undefinedness. I would be extremely hesitant to call</div><div><br></div><div>mAdd :: Int -> Int -> Maybe Int</div>
<div><br></div><div>"monadic" unless it was actually using a monadic interface to Maybe. Indeed, I would call it "pure" and "functional". Similarly for:</div><div><br></div><div>(++) :: [a] -> [a] -> [a]</div>
<div><br></div><div>The result types are monadic insofar as they have a free type variable, but they are also entirely pure and functional.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
You can argue that well it's just in the types -- you pays your money and<br>
takes you<br>
choice. (Viz., if your function works with effects then it should be<br>
expressed in its type.)<br></blockquote><div><br></div><div>Yes, this. If you need a list, use a list. If you need simple undefinedness, use Maybe, etc.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
But then this becomes the price of doing everything in a strong functional<br>
framework. To take one counter example, the Standard ML combines functional<br>
programming and effects without forcing this reification on the programmer.<br></blockquote><div><br></div><div>I don't know SML. How is our list "monadic" and theirs not? In particular, how is Haskell "forcing" the reification while SML does not?</div>
<div><br></div></div>