[Haskell-cafe] Is there a nicer way to do this?
dons at galois.com
Sun Jul 6 20:42:04 EDT 2008
> Don Stewart wrote:
> >>segment :: Int -> [a] -> [[a]]
> >>segment 0 _ = 
> >>segment _  = 
> >>segment n x = (take n x) : segment n (drop n x)
> >The first set of parens can go,
> > segment n x = take n x : segment n (drop n x)
> >>I did a version of this which used splitAt but I wasn't sure whether it
> >>was going to buy me anything re performance that would justify its
> > splitAt n xs = (take n xs, drop n xs)
> Thanks. That is odd, though. It makes me wonder what to expect re
> optimization. Would the compiler/runtime know that splitAt could be
> done in a single pass?
Not with that definition. It would require some moderately unusual fusion
combining the take and drop into a single fold with the (,) on the inside,
rather than on the outside.
However, GHC actually implements splitAt as:
splitAt (I n) ls
| n < 0 = (, ls)
| otherwise = splitAt' n ls
splitAt' :: Int -> [a] -> ([a], [a])
splitAt' 0 xs = (, xs)
splitAt' _ xs@ = (xs, xs)
splitAt' m (x:xs) = (x:xs', xs'')
(xs', xs'') = splitAt' (m - 1) xs
So there may be some benefit.
More information about the Haskell-Cafe