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 pack
s 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.
来源:https://stackoverflow.com/questions/26778415/using-overloaded-strings