Использование перегруженных строк
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
везде, где 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"
РЕДАКТИРОВАТЬ Вы также можете добавить default (Text)
в верхней части вашего модуля, чтобы использовать его Text
вместо String
по умолчанию.