[Haskell-cafe] "no-coding" functional data structures via lazyness

Dave Bayer bayer at cpw.math.columbia.edu
Mon Jul 9 17:57:55 EDT 2007


Learning Haskell, the Prelude.ShowS type stood out as odd, exploiting  
the implementation of lazy evaluation to avoid explicitly writing an  
efficient concatenable list data structure. This felt like cheating,  
or at least like using a screwdriver as a crowbar, to be less  
judgmental.

Recently I was playing with prime sieves and various heap data  
structures, while rereading Chris Okasaki's "Purely Functional Data  
Structures", and it dawned on me:

> merge xs@(x:xt) ys@(y:yt) = case compare x y of
>     LT -> x : (merge xt ys)
>     EQ -> x : (merge xt yt)
>     GT -> y : (merge xs yt)
>
> diff xs@(x:xt) ys@(y:yt) = case compare x y of
>     LT -> x : (diff xt ys)
>     EQ -> diff xt yt
>     GT -> diff xs yt
>
> merge' (x:xt) ys = x : (merge xt ys)
>
> primes = ps ++ (diff ns $ foldr1 merge' $ map f $ tail primes)
>     where ps  = [2,3,5]
>           ns  = [7,9..]
>           f p = [ m*p | m <- [p,p+2..]]

The code is very fast for its size; I haven't seen Haskell code  
posted on the web that comes close, and it is faster than any of my  
other tries (I posted this code to http://www.haskell.org/haskellwiki/ 
Prime_numbers). Effectively, it steals a heap data structure out of  
thin air by exploiting the implementation of lazy evaluation. It  
would seem that GHC's core data structures are coded closer to the  
machine that anything I can write _in_ Haskell. So much for studying  
how to explicitly write a good heap!

So is there a name for this idiom, "no-coding" a classic data  
structure through lazy evaluation? Are there other good examples?



More information about the Haskell-Cafe mailing list