[Haskell-cafe] Data.ByteString.dropWhile

Donald Bruce Stewart dons at cse.unsw.edu.au
Tue Jul 10 01:17:02 EDT 2007


drtomc:
> Well, maybe I shoud be asking a higher level question then.
> 
> I have a function
> 
> tidy = reverse . dropWhile punk . reverse . dropWhile punk
>    where
>    punk = isPunctuation . chr . fromIntegral
> 
> which is leading to a significant amount of allocation, and you can see why.
> 
> The way I'd like to write it is
> 
> tidy = dropWhile punk . dropWhileEnd punk
>    where ....
> 
> which has the obvious advantage of avoiding quite a bit of
> intermediate allocation.
> 
> Is there a another way?
> 
> I note that since I'm using a nice declarative language, the compiler
> CLEARLY should be transforming the first form into the second. :-)

I'd just manually write a 'tidy' loop (in the Data.ByteString style) (which
would avoid all allocations), since it seems pretty useful.

Something in this style:

    findIndexOrEnd :: (Word8 -> Bool) -> ByteString -> Int
    findIndexOrEnd k (PS x s l) =
         inlinePerformIO $ withForeignPtr x $ \f -> go (f `plusPtr` s) 0
      where
        go !ptr !n | n >= l    = return l
                   | otherwise = do w <- peek ptr
                                    if k w
                                        then return n
                                        else go (ptr `plusPtr` 1) (n+1)

If its costly, since that'll make it non-costly.

-- Don


More information about the Haskell-Cafe mailing list