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
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to