[Haskell-cafe] Is there a nicer way to do this?
Don Stewart
dons at galois.com
Sun Jul 6 20:42:04 EDT 2008
mfeathers:
> Don Stewart wrote:
> >mfeathers:
> >>
> >>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
> >>ugliness.
> >
> >Besides,
> >
> > 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
where
splitAt' :: Int -> [a] -> ([a], [a])
splitAt' 0 xs = ([], xs)
splitAt' _ xs@[] = (xs, xs)
splitAt' m (x:xs) = (x:xs', xs'')
where
(xs', xs'') = splitAt' (m - 1) xs
So there may be some benefit.
-- Don
More information about the Haskell-Cafe
mailing list