I see two approaches here. You can do some import shuffling and just alias the functions you need to have less general types, such as
import qualified Text.Regex.Posix as P
import Text.Regex.Posix hiding ((=~))
(=~) :: RegexContext Regex String target => String -> String -> target
(=~) = (P.=~)
Then you don't have to change the code throughout your file. This can lead to confusion though, and it requires FlexibleContexts
to work (not a big deal).
Alternatively you can create your own Python-like syntax for specifying the type:
r :: String -> String
r = id
u :: Text -> Text
u = id
b :: ByteString -> ByteString
b = id
example :: Bool
example = r"test" =~ r"te.t"
splitComma :: Text -> Text
splitComma = Data.Text.splitOn (u",")
But this will require you to edit more of your code. It doesn't use any extra language extensions and the code to implement it is very simple, even in comparison to the first method. It Also means that you'll have to use parentheses or $
signs more carefully, but you can also use the r
, u
, and b
functions as, well, functions.