Re: [Haskell-cafe] Is there a nicer way to do this?
Don Stewart [EMAIL PROTECTED] writes: 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. Uhm, but I'm quite sure I saw a paper about how the garbage collector could discover this, and update both thunks simultaneously. (Unfortunately, I can't seem to find it now.) -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Is there a nicer way to do this?
segment :: Int - [a] - [[a]] segment 0 _ = [] segment _ [] = [] 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. Michael ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is there a nicer way to do this?
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) -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is there a nicer way to do this?
On Sun, Jul 6, 2008 at 16:45, Michael Feathers [EMAIL PROTECTED] wrote: segment :: Int - [a] - [[a]] segment 0 _ = [] segment _ [] = [] 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. You can use segment n = takeWhile (not . null) . unfoldr (Just . splitAt n) I don't know how it compares in performance. It's from http://www.haskell.org/haskellwiki/Blow_your_mind - John ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is there a nicer way to do this?
On Sun, Jul 6, 2008 at 5:25 PM, John Hamilton [EMAIL PROTECTED] wrote: On Sun, Jul 6, 2008 at 16:45, Michael Feathers [EMAIL PROTECTED] wrote: segment :: Int - [a] - [[a]] segment 0 _ = [] segment _ [] = [] 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. You can use segment n = takeWhile (not . null) . unfoldr (Just . splitAt n) I don't know how it compares in performance. It's from http://www.haskell.org/haskellwiki/Blow_your_mind Watch out for negative numbers, though. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is there a nicer way to do this?
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' _ [EMAIL PROTECTED] = (xs, xs) splitAt' m (x:xs) = (x:xs', xs'') where (xs', xs'') = splitAt' (m - 1) xs So there may be some benefit. -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe