Reputation: 4127
This works:
{-# LANGUAGE OverloadedStrings #-}
myFunc :: Text -> String
myFunc "" = "nothing"
myFunc other = "something!"
Without the OverloadedStrings
extension however, ""
is of type String
so it doesn't compile. Using a function like myFunc (pack "")
is not allowed in patterns.
Haskell Bytestrings: How to pattern match? contains some suggestions that should work, however in this case I'm wondering if there is something special about the fact that it works with OverloadedStrings
that would allow a better way?
Upvotes: 8
Views: 1863
Reputation: 120711
The most direct translation is with ViewPatterns
{-# LANGUAGE ViewPatterns #-}
import qualified Data.Text as Txt
myFunc (Txt.unpack->"") = "nothing"
myFunc _other = "something!"
The best translation, albeit probably too specific for your actual use case, is of course
myFunc txt | Txt.null txt = "nothing"
| otherwise = "something!"
You could also go nuts and make up a pattern synonym:
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}
pattern T :: String -> Txt.Text
pattern T str <- (Txt.unpack -> str)
where T = Txt.pack
and then
myFunc (T"") = "nothing"
myFunc _other = "something"
Arguably, OverloadedStrings
is a more sane extension than ViewPatterns
, and certainly saner than PatternSynonyms
.
Upvotes: 14
Reputation: 15949
The easiest way to solve this is to use either guards as @melpomene suggests or case expressions.
testfunc :: Text -> String
testfunc s | s == pack "" = "nothing"
| otherwise = "someting"
testfunc' :: Text -> String
testfunc' s = case unpack s of
"" -> "nothing"
_ -> "something"
The inner workings of LANGUAGE OverloadedStrings
uses the IsString
typeclass, if I remember correctly, and I guess it also relies on INLINING
to make this efficient.
Upvotes: 9