Search code examples
haskellbytestring

chunksOf analog for ByteString?


I need to split bytestring into list of bytestrings diving first one by 100 characters. For lists, I can use chunksOf but not for ByteString.

Is there some proper way to do this?


Solution

  • Both ByteString and Lazy.Bytestring have splitAt functions which you can use to unfoldr a list.

    import Data.List (unfoldr)
    import Data.Int (Int64)
    
    import qualified Data.ByteString as BS
    import qualified Data.ByteString.Lazy as Lazy
    
    justWhen :: (a -> Bool) -> (a -> b) -> (a -> Maybe b)
    justWhen f g a = if f a then Just (g a) else Nothing
    
    nothingWhen :: (a -> Bool) -> (a -> b) -> (a -> Maybe b)
    nothingWhen f = justWhen (not . f)
    
    chunksOf :: Int -> BS.ByteString -> [BS.ByteString]
    chunksOf x = unfoldr (nothingWhen BS.null (BS.splitAt x))
    
    chunksOf' :: Int64 -> Lazy.ByteString -> [Lazy.ByteString]
    chunksOf' x = unfoldr (nothingWhen Lazy.null (Lazy.splitAt x))
    

    Building bytestrings for an example is easier with OverloadedStrings

    {-# LANGUAGE OverloadedStrings #-}
    
    main = do
        print $ chunksOf 3 ""
        print $ chunksOf 3 "Hello World!"
        print $ chunksOf' 3 ""
        print $ chunksOf' 3 "Hello, World"