[Haskell-cafe] Re: New to Haskell

Jon Fairbairn jon.fairbairn at cl.cam.ac.uk
Tue Dec 18 04:56:36 EST 2007

"Cristian Baboi" <cristi at ot.onrc.ro> writes:

> What I should have been told about upfront:
> - the syntax for an expression

Since there are only declarations and expressions, the
syntax of an expression involves pretty much all of the
language, so it would be difficult to tell it "upfront".

> - the syntax for a block

Not sure what you mean by "block". 

do a <- [1..10]
   b <- [3,4]
   return (a,b)

is an expression... you can write that same expression as
do {a <- [1..10]; b <- [3,4]; return (a,b)} too.

> - the adhoc syntax rules (how to distinguish among a tuple
> and a  pharanthesized expression

a tuple has commas in it. I'll grant that (x) not being a
1-tuple is a little ad-hoc, but there really is very little
ad-hockery in Haskell (and a 1-tuple behaves very much like
a plain value after all).

> and how to find the start and end of a block for example )

again, I don't know what you mean by block, but if you write
the above expression with the braces ({}), it's obvious, I
think, and the layout rule just inserts braces as
necessary when the indentation changes.

do a
  c  -- this is less indented, so will cause the end of the do.

> - the fact that lambda expressions are not the same thing
> as "algebraic data" values

It might help to know why you think they might be the same;
the syntax is different and the name is different...

> - what guarantees are made by the LANGUAGE that an IO action
> (such as  do  putStrLn "Hello world" ) is not performed
> twice

As has been pointed out, «do putStrLn "Hello world"» is an
expression that you can bind to a variable and use as many
times as you like. Incidentally, it means the same as
«putStrLn "Hello World"»; do connects a sequence of bindings
and expressions, so you don't need it if there's nothing to
be connected to.

> - the lambda expressions can be written (input) but cannot
> be printed  (output)

This is a fundamental property of the language.  A lambda
expression is programme and at runtime the system doesn't
know one lambda expression from another (all it can do with
one is apply it to something).

> The biggest problem for me, so far, is the last one.

I can't see how your example illustrates that, I'm afraid.

> Here is some strange example:

> What I don't understand is why I'm forced to use guards like
> x==aa in cc,  when aa is clearly bounded (is 7) and why in
> function h, the bounded u and  v become free variables in
> the case expression.

I would have liked the language design to have permitted
case to pattern match against variables too, but the
question is, what would the syntax be?  There was a fair bit
of discussion about this when the language was designed (and
since), but no-one could come up with a good way of doing
it. One aspect of it is this: we want

f 0 = 42
f x = 3*x

to work, and we want all function definitions to be
translated into the core language in the same way,
so you get
f = \a -> case a of
            0 -> 42
            x -> 3*x

and given that, you can't have a variable on the LHS of ->
do anything other than get bound to the value of the
expression in the case (a in the example). It's not just a
the top level, either:

f Nothing = 0
f (Just n) = n+1

just means
f = \v -> case v of
            Nothing -> 0
            Just n -> n+1

so you can't have variables inside constructors do anything
but get bound at that point.

Jón Fairbairn                                 Jon.Fairbairn at cl.cam.ac.uk
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2007-05-07)

More information about the Haskell-Cafe mailing list