2014-11-06 18 views
10

OverloadedStrings Erweiterung ist wirklich sehr nützlich, aber es hat einige Nachteile. Betrachten Sie die folgende Funktionsdefinition:Verwenden überladener Strings

someFunction :: ToJSSTring a => a -> IO() 
someFunction = js_function . toJSSTring 

In diesem Fall, wenn, wenn ich einen literalen Wert übergeben will Ich habe eine Art Signatur explizit hinzufügen, wenn OverloadedStrings aktiviert ist:

someFunction ("This is plain string" :: String) 
someFunction ("And this one is Text" :: Data.Text.Text) 

Der Grund dafür Notwendigkeit ist ziemlich offensichtlich, ich nehme an, OverloadedStrings wurde entwickelt, um die Weitergabe von Literalwerten zu Funktionen, die strenge Typ-Signaturen zu erleichtern, so dass der Entwickler frei von Schreiben pack s überall, wo ein Text Wert benötigt wird.

Die Frage ist, gibt es eine Möglichkeit, sagen wir, alle String-Literale ohne Typ Signaturen Text oder String Standard? Oder sollte ich meinen Code nur in allgemeine Funktionen (mit der ToJSString Typ-Einschränkung) und in beliebige andere, die für ihre Argumente strikte Typ-Signaturen haben, aufteilen?

Antwort

22

Sie können auf ExtendedDefaultRules drehen als auch (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 Sie auch default (Text) an die Spitze des Moduls möchten hinzufügen es Text statt String verwenden standardmäßig haben.

+1

Sie hört nie auf, mich zu überraschen! Danke vielmals. –

Verwandte Themen