2014-11-06 11 views
10

OverloadedStrings Rozszerzenie jest bardzo przydatne, ale ma pewne wady. Rozważmy następującą definicję funkcji:Używanie Przeciążonych Ciągów

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

W tym przypadku, gdy jeśli chcę przekazać wartość literalną muszę dodać podpis typu jawnie gdy OverloadedStrings jest włączona:

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

Powodem tego Konieczność jest dość oczywista. Przypuszczam, że zaprojektowano OverloadedStrings, aby ułatwić przekazywanie wartości literalnych do funkcji, które mają ścisłe podpisy typów, dzięki czemu programista może napisać wszędzie tam, gdzie potrzebna jest wartość .

Pytanie brzmi, czy na przykład domyślnie wszystkie ciągi literowe bez podpisów typu na Text lub String? Czy powinienem po prostu podzielić mój kod na funkcje ogólne (z ograniczeniem typu ToJSString) i arbitralne, które mają ścisłe podpisy typów dla swoich argumentów?

Odpowiedz

22

Można włączyć ExtendedDefaultRules, jak również (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 Można również dodać default (Text) do górnej części modułu, aby go używać Text zamiast String domyślnie.

+1

Nigdy nie przestajesz mnie zadziwiać! Wielkie dzięki. –

Powiązane problemy