[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