问题
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?
回答1:
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