Использование Перегруженных Строк
OverloadedStrings
расширение действительно очень полезно, однако у него есть некоторые недостатки.
Рассмотрим следующее определение функции:
someFunction :: ToJSSTring a => a -> IO ()
someFunction = js_function . toJSSTring
В этом случае, если я хочу передать литеральное значение, я должен добавить подпись типа явно, когда OverloadedStrings
включен:
someFunction ("This is plain string" :: String)
someFunction ("And this one is Text" :: Data.Text.Text)
Причина этой необходимости вполне очевидна, я полагаю, что OverloadedStrings
был разработан, чтобы облегчить передачу литеральных значений функциям, которые имеют строгие сигнатуры типа, что делает разработчика свободным от написания pack
s везде, где требуется значение Text
.
Вопрос в том, можно ли, скажем, по умолчанию использовать все строковые литералы без сигнатур типа Text
или String
? Или я должен просто разделить свой код на общие функции (с ограничением типа ToJSString
) и произвольные, которые имеют строгие сигнатуры типа для своих аргументов?
1 ответ:
Вы также можете включить
ExtendedDefaultRules
(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 вы также можете добавить
default (Text)
в верхнюю часть вашего модуля, чтобы он использовалText
вместоString
по умолчанию.