[Haskell-cafe] Tutorial on Haskell: Use closures
Paul Johnson
paul at cogito.org.uk
Sun Apr 22 04:58:10 EDT 2007
Closures look like magic to those who don't know them. So you might try
something like this (which I have not compiled BTW):
> -- Haskell version
>
> data Train = Train {departs :: Time, platform :: Int }
>
> departsBefore :: Time -> Train -> Bool
> departsBefore t train = t < departs train
>
> beforeAfter :: Time -> [Train] -> ([Train], [Train])
> beforeAfter t = partition (departsBefore t) departures
The crucial point is that "partition" takes a function argument, but
that function has to carry the 't' argument with it.
The only way you could write "partition" as a generic function in Java
would be to define an interface class "discriminator" which is passed to
"partition". "discriminator" is then specialised for every closure you
want to create. This is a lot of code for something that can be done
in-line in Haskell. The fact that all functions are curried by default
also saves having lots of lambdas.
You might also show how deforestation optimises functional pipelines.
Lots of Haskell code contains lines of the form
> foo = bar x $ foldr1 boz $ map baz ls
In other FP languages (like Erlang) you can use this style, but it tends
to be inefficient because of all the intermediate lists. Haskell is
free to arrange the functions how it likes because of purity. Hence it
can optimise this pipeline into a single loop. Obviously you know much
more about this than I do, but to me its one of the biggest arguments in
favour of purity.
Paul.
More information about the Haskell-Cafe
mailing list