[Haskell-cafe] Is "take" behaving correctly?

rahn at ira.uka.de rahn at ira.uka.de
Wed Sep 12 04:08:25 EDT 2007


> take 1000 [1..3] still yields [1,2,3]

You can think about take n as: Take as much as possible, but at most n  
elements. This behavior has some nice properties as turned out by  
others, but there are some pitfalls. We have

length . take n /= const n

in general, instead only

length . take n `elem` map const [0..n]

holds. Therefore head . length n is unsafe for all n, even strict  
positive ones. Moreover, it is easy to produce tricky code. Assume you  
want to know, whether the prefixes of length k are equal and write

pref_eq k xs ys = take k xs == take k ys

This seems to be a straightforward implementation with good  
properties. Now play a bit with it:

Prelude> pref_eq 3 "ab" "abc"
False
Prelude> pref_eq 3 "ab" "ab"
True
Prelude> map (pref_eq 3 "ab") $ Data.List.inits "abc"
[False,False,True,False]

Uhh, this is not what everybody expects at first glance. In particular, if

pref_eq k xs ys == False

then *not* necessarily

pref_eq k xs (init ys) == False.

As always, quickCheck is your friend to assure (or reject) such a property.

/BR


More information about the Haskell-Cafe mailing list