Search code examples
haskellpattern-matchingbytestringpattern-synonyms

Haskell Bytestrings: How to pattern match?


I'm a Haskell newbie, and having a bit of trouble figuring out how to pattern match a ByteString. The [Char] version of my function looks like:

dropAB :: String -> String
dropAB []       = []
dropAB (x:[])   = x:[]
dropAB (x:y:xs) = if x=='a' && y=='b'
                  then dropAB xs
                  else x:(dropAB $ y:xs) 

As expected, this filters out all occurrences of "ab" from a string. However, I have problems trying to apply this to a ByteString.

The naive version

dropR :: BS.ByteString -> BS.ByteString
dropR []         = []
dropR (x:[])     = [x]
<...>

yields

Couldn't match expected type `BS.ByteString'
       against inferred type `[a]'
In the pattern: []
In the definition of `dropR': dropR [] = []

[] is clearly the culprit, as it is for a regular String not a ByteString. Subbing in BS.empty seems like the right thing but gives "Qualified name in the binding position: BS.empty." Leaving us to try

dropR :: BS.ByteString -> BS.ByteString
dropR empty              = empty        
dropR (x cons empty)     = x cons empty
<...>

this gives "parse error in pattern" for (x cons empty). I don't really know what else I can do here.

As a side note, what I'm trying to do with this function is to filter out a specific UTF16 character from some text. If there's a clean way to accomplish that, I'd love to hear it, but this pattern matching error seems like something that a newbie haskeller should really understand.


Solution

  • You can use view patterns for such things

    {-# LANGUAGE ViewPatterns #-}    
    import Data.ByteString (ByteString, cons, uncons, singleton, empty)
    import Data.ByteString.Internal (c2w) 
    
    dropR :: ByteString -> ByteString
    dropR (uncons -> Nothing) = empty
    dropR (uncons -> Just (x,uncons -> Nothing)) = singleton x
    dropR (uncons -> Just (x,uncons -> Just(y,xs))) =
        if x == c2w 'a' && y == c2w 'b'
        then dropR xs
        else cons x (dropR $ cons y xs)