Re: [Haskell-cafe] Is there a nicer way to do this?

2008-07-06 Thread Ketil Malde
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


Re: [Haskell-cafe] Is there a nicer way to do this?

2008-07-06 Thread Don Stewart
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


Re: [Haskell-cafe] Is there a nicer way to do this?

2008-07-06 Thread Evan Laforge
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?

2008-07-06 Thread John Hamilton
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?

2008-07-06 Thread Don Stewart
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