[Haskell] Newbie quick questions

Cale Gibbard cgibbard at gmail.com
Tue Oct 4 07:54:34 EDT 2005

I wouldn't really consider any of those a particularly quick question,
but I'll give them a shot :)

On 04/10/05, Mike Crowe <mike at mikeandkellycrowe.com> wrote:
> Hi folks,
> I ran across Haskell at the Great Win32 Computer Language Shootout.  A
> friend approached me with a potential large application to develop.  The
> idea of a language which can reduce time to design and make better code
> is very intriguing.
> I was looking at prototyping in Python using wxWindows as the GUI.  I
> see Haskell has wxWindows libraries as well.
> So, here's some newbie questions I couldn't get from 2-3h on the various
> web sites:
> 1) Can I develop a Windows application to sell?  Or is Haskell not
> really geared for that?

Well, of course -- the compilers are free, but there's no reason I can
see that you couldn't sell an app that was written in Haskell. You'd
need to be careful about the licenses of libraries that you use. I
think that binaries produced with GHC are currently linked with libgmp
which is under the LGPL, so you may have to be careful there as well.
There are a variety of cross platform GUI libraries available.

> 2) Say a team wants to develop a larger application, like a CRM system.
> In "thinking" in functional programming, can a team split up work and
> implementation and work together?  In other words, how easily does
> Haskell adapt to a team approach?

Haskell supports quite a few different abstractions which would let
you code things separately. In fact, most Haskell code is
referentially transparent, so you usually don't even need the rest of
the app to run in order to properly test a particular function (just
the dependencies of that function). The type system is very nice at
eliminating potential for bugs and helping to document how things fit

The largest application that I've written personally is a pipeline
scheduler and register allocator as part of a compiler for a high
level signal processing language. The algorithm was a search and
backtracking algorithm, which carried on into the register allocation
(if a schedule couldn't be register allocated, it would have to
backtrack into the scheduler). A nice thing here is that I didn't have
to think of it as such, as all the backtracking occurred
automatically, as I used the list monad for nondeterminism. After
design of the algorithm which would be used, it only took a couple
weeks to implement and test and was around 1000 lines, which was about
1/2 documentation, and ~250 lines of which was a parser generator for
an assembly/dependency language, which built a parser based on the
opcodes available. I suspect that a similar project in C would be at
least 10 times as much code, and would not have been manageable in the
time I had.

Many things are very elegantly expressed in Haskell. I recommend that
you try writing some small applications in it to get a feel for what
it's like.

> 3) Again, using a CRM tool as an example, what is the advantage to
> developing an application like this in Haskell vs. any other language?
> If I really invest the time, can I get this done quicker in Haskell?
> Sell me on this, please.

Haskell has quite a lot of nice features which help in various
different ways. I won't even try to list them all for you, but point
out a few I find nice. This really takes some exploring on your own in
order to find out what is available, and how it might help. Also keep
in mind that a lot has been written on the wiki
(http://www.haskell.org/hawiki/) and in these mailing lists as to neat
ways in which to use Haskell's features.

Referential transparency I already mentioned, is incredibly nice to
have. It basically consists of the guarantee that functions are
completely determined by what values they return for given inputs -
there is no hidden global state or side effects. This makes it much
easier to prove that programs do what they are supposed to do, as well
as to understand the code.

The type system itself is marvellous in its ability to control how
code is used and catch bugs at compile time, and prove various simple
constraints hold on the code. To a very large extent, when programs
compile, they also work as intended. Of course there are still bugs
involved with using the wrong algorithm, but nothing can really
prevent that. The type system catches a large portion of the errors
which occur from attempting to fit existing pieces of code together in
an unsuitable way.

This is incredibly helpful when approaching a large library of
existing code and wanting to write a new function based on it. The
first thing to do is to look at the type of the function you want to
write, and the types of the functions available. Your options in
searching for useful code will often be quite restricted by the types
which makes your job easier.

When state and side effects are needed in Haskell, these things
(though not only these things) are treated specially through the use
of monads, which are a nice abstraction of both containers and models
of computation. The monad being used occurs directly in the types of
the functions and values involved, making it clear when it is in use,
and preventing abuses.

For example, if I have a function of type String -> String, then it
cannot launch missiles (or do any IO whatsoever) while computing its
result, simply because of its type. If it could possibly do some IO,
it would have the type String -> IO String, which is somewhat rarer,
and can not be used in the same places as a function of type String ->
String. At first, this seems inconvenient, but in general, it helps to
structure your program in such a way that makes it easier to reason
about and work with.

> 4) I'm a very top-down programmer.  I like to start at the "big-picture"
> and work my way down in implementation.  Does this adapt to Haskell, or
> am I missing the point?

>From my experience, Haskell is quite good at this. You might be
interested in type classes, which are effectively a way to express a
relation between types in a program, and specify functionality between
those types wherever the relation holds. This is how "overloaded"
functions work in Haskell. For example, in the standard Prelude which
is generally used in every Haskell program, there is the class Eq:

class  Eq a  where
    (==), (/=) :: a -> a -> Bool

        -- Minimal complete definition:
        --      (==) or (/=)
    x /= y     =  not (x == y)
    x == y     =  not (x /= y)

This single-parameter class basically defines the equality testing
operations. If "Eq a" holds for some type "a", then it is possible to
compare values of that type for equality. When you create types of
your own, you get to specify an instance of Eq for your type to say
how they should be compared, or write "deriving Eq" at the end of your
data or newtype declaration, which will provide a sane default.

Typeclasses in general let you specify functionality in an abstract
way, and then specify a variety of implementations for that
functionality and keep that entirely separate from the code which uses
it. In this way, it is possible to provide simple instances when
starting out, and provide more sophisticated implementations of the
same behaviour later, without rewriting the code which uses it at all.
(Just providing an input of a different type is enough.)

> TIA!
> Mike

hope this is useful
 - Cale

More information about the Haskell mailing list