OverloadedStrings extension is really very useful, however it has some downsides.
Consider the following function definition:
someFunction :: ToJSSTring a => a -> IO ()
someFunction = js_function . toJSSTring
In this case when if I want to pass a literal value I have to add a type signature explicitly when OverloadedStrings is enabled:
someFunction ("This is plain string" :: String)
someFunction ("And this one is Text" :: Data.Text.Text)
The reason for this necessity is quite obvious, I suppose OverloadedStrings was designed to ease the passing of literal values to functions that have strict type signatures, making the developer free from writing packs everywhere where a Text value is needed.
The question is there any way, say, to default all string literals without type signatures to Text, or String? Or should I just split my code to general functions (with the ToJSString type constraint) and arbitrary ones, which have strict type signatures for their arguments?
You can turn on ExtendedDefaultRules as well (https://www.fpcomplete.com/user/snoyberg/random-code-snippets/overloadedstrings-defaults):
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExtendedDefaultRules #-}
import Data.Text (Text, pack)
newtype JSString = JSString Text
    deriving Show
class ToJSString a where
    toJSString :: a -> JSString
instance ToJSString [Char] where
    toJSString = toJSString . pack
instance ToJSString Text where
    toJSString = JSString
someFunction :: ToJSString a => a -> IO ()
someFunction = print . toJSString
main :: IO ()
main = someFunction "Hello World"
EDIT You may also want to add default (Text) to the top of your module to have it use Text instead of String by default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With