[Haskell-cafe] About print and side-effects
Chris Kuklewicz
haskell at list.mightyreason.com
Sun Dec 18 15:55:05 EST 2005
Daniel Carrera wrote:
> Hi all,
>
> The recent responses to my first question (thanks guys!) included the
> following bit:
>
> main = print (fact 42)
You can use a "do" block:
main = do
print (fact 42)
which also works.
But for a single thing of type (IO _) the "do" is optional.
>
>
> Now, print is a side-effect. Shouldn't it involve a do-block or a nomad
> or one of those scary things you hear about when learning about side
> effects in functional programs? How come 'print' is allowed to exist
> alone if it's a side-effect?
>
> Thanks for the help.
>
> Cheers,
> Daniel.
By nomad you seemed to either be ridiculing or misspelling monad. The
right-hand-side of main must have type "IO _" where _ is whatever type
you program returns, often "()". The print command has type "print ::
forall a. (Show a) => a -> IO ()" so the type of "print (fac 42)" is the
desired type "IO ()". Thus there is no need for special "do" syntax or
monad operators >> or >>=.
Lets say you want to print several values:
main = do putStr "(fact 42) is "
print (fact 42)
putStr "(fact 1) is "
print (fact 1)
That is the do-syntax with the whitespace sensitive 2D layout syntax.
This is equivalent to
main = do { putStr "(fac 42) is "; print (fact 42);
putStr "(fac 1) is "; print (fact 1); }
Now do-syntax is just sugar for (slighty simplified here):
main = putStr "(fac 42) is " >> print (fact 42) >>
putStr "(fac 1) is "">> print (fact 1)
Where >> is an infix, binary operator that takes commands and returns
the concatenated command. So the above is a single action that is the
concatenation of the four IO commands.
Since it is now a single command, no "do" is needed.
The value of the whitespace form is that some people are happier reading
and writing it. The value of the {;} syntax is that it is very familiar
and perhaps more pleasing to some people and perhaps more pleasing to
some code generaion tools. The value of the de-sugared form is that it
*is* the Monadic form (which acutally uses >>= and case statements,
details in the language definition
http://www.informatik.uni-freiburg.de/~thiemann/haskell/haskell98-report-html/exps.html#sect3.14
)
Sometime the Monadic form can be used to remove unhelpful variable
bindings that clutter code. This can lead to clearer code.
Note that the whitespace layout form has much less punctuation, and only
a single two letter keyword. Unlike python the decision about how much
to indent is up to the author, but the command must be lined up.
--
Chris
More information about the Haskell-Cafe
mailing list