Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Overloaded Strings

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?

like image 314
Geradlus_RU Avatar asked Nov 06 '14 11:11

Geradlus_RU


1 Answers

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.

like image 130
Michael Snoyman Avatar answered Nov 01 '22 20:11

Michael Snoyman