[Haskell-cafe] Re: First steps in Haskell

Cale Gibbard cgibbard at gmail.com
Sun Jan 22 22:52:44 EST 2006

> FWIW:  This is my second or third day with Haskell.  I was totally stumped
> until I searched out "Yet Another Haskell Tutorial".  I tried starting with
> "A Gentle Introduction...", but it never told me how to get started.  It
> talked at great length about the language, and I'm certain that it will be
> very useful in a week or so, but it sure isn't the way to get started.
> So he's not unique.  I couldn't figure out why Hugs wouldn't interpret what
> I was certain were legitimate Haskell statements.  (I'm still not sure why.
> Gentle introduction is a bit of a rough start.  I'm confused between type
> declarations and variable assignments, etc.  I'm sure this will work out
> over time, but right now the confusion is pretty severe.)  And in "A Gentle
> Introduction..." I've yet to encounter a module statement.  Perhaps I
> missed it, perhaps it's new, perhaps it's only used in batch compilation?
> Well, I'll find out eventually.  "Yet Another ..." mentioned it right off,
> and I got Hello World working within 5 minutes (with my own customizations,
> to also append the value of x onto the message).
> A language manual is not a tutorial.  It's important, but first you need a
> place to start.

Yeah, the "Gentle Introduction" could reallly only be considered
gentle if you're already familiar with other functional languages such
as ML, or perhaps in comparison to reading the report. Yet Another
Haskell Tutorial is usually where I point newcomers.

The reason that GHCi and Hugs don't accept things like function and
type declarations is that they are intended only to evaluate
expressions (that is, things which evaluate to values), as opposed to
reading declarations. You're expected to put all your declarations in
a file, where all the various dependencies can be resolved, and then
load that with your favourite interactive environment for testing, but
not really so much for development. I like to keep an editor open with
my module alongside a running GHCi session. When I'm ready to try out
a new declaration, I'll save the file, and type ":r" in GHCi, which
reloads my file.

In GHCi (as opposed to hugs) it's possible to make function and value
declarations at the prompt with let:

Prelude> let fac n = product [1..n]
Prelude> fac 12

However, these are not very permanent -- they go away when you reload
your file, and future declarations shadow previous ones. There's also
no way to save all the declarations you've made like this, and as
mentioned, it only works for functions and values. So really, it's a
lot nicer to save all your declarations in a file as you work.

As to the confusion between type and value declarations (it's a little
odd to call them "assignments" by the way, because they're really more
declarations -- you can't reassign them later), it should sort itself
out on its own in a short while, but the basic difference is that
value declarations define the value to which some name or pattern
evaluates, whereas type declarations say what type of thing it should
work out to.

If you write:
x :: String
x = [1,2,3]

you'll get an error, because [1,2,3] isn't a String. Haskell can
largely work out appropriate types for things on its own, so if you're
ever sure you have the definition right, but not sure exactly what
type it should have, you can ask GHCi or Hugs to tell you using
:t expr
where expr is the expression you'd like the type for.

Haskell's type system is a good way to eliminate wide classes of
potential bugs. In my experience, I'd estimate that 95% or so of the
bugs which I'd experience at runtime in most 'popular' languages with
lesser type systems (C, Java, Lisp, Ruby etc.) become compile time
errors. The vast majority of what remains are actual design flaws.
When things compile, they usually work, to a much greater extent than
I'd come to expect in most other languages.

That said, the type system works a lot better when you include type
declarations, because it provides lots of sanity checks -- it will
still make sure that the types it infers for the functions and values
are compatible with the types you're giving them explicitly. Also,
error messages from the compiler can get a lot tighter and can point
you at the problems in your code more swiftly. So even though it's
largely optional, it's good to include types for things whenever it's
not too inconvenient.

hope this helps,
 - Cale

More information about the Haskell-Cafe mailing list