[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