Ответ 1
Это немного перебор, но одно решение состоит в объединении OverloadedStrings
и RebindableSyntax
. Расширение RebindableSyntax
вызывает все вызовы неявных функций, которые использует синтаксис Haskell для обозначения любых функций в области видимости; например, целые литералы используют любой fromIntegral
, не обязательно Prelude.fromIntegral
. В качестве побочного эффекта Prelude
уже неявно импортируется, поэтому вам нужно сделать это вручную. Пока вы импортируете его, не должно быть никаких проблем с синтаксисом, используя неявную функцию неявно (я думаю - я на самом деле не использовал эту технику). В сочетании с OverloadedStrings
это приводит к тому, что "foo"
преобразуется в fromString "foo"
для любого fromString
в области видимости, не обязательно Data.String.fromString "foo"
. Поэтому создание fromString
синонимом pack
будет делать то, что вы хотите. Полный пример:
{-# LANGUAGE OverloadedStrings, RebindableSyntax #-}
import Prelude
import qualified Data.Text as T
import qualified Data.Text.IO as T
fromString :: String -> T.Text
fromString = T.pack
main :: IO ()
main = T.putStrLn "Hello, world!"
Это отлично работает, и изменение main
на main = putStrLn "Hello, world!"
вызывает желаемую ошибку:
TestStrings.hs:11:17:
Couldn't match expected type `String' with actual type `T.Text'
Expected type: [Char] -> String
Actual type: String -> T.Text
In the first argument of `putStrLn', namely `"Hello, world!"'
In the expression: putStrLn "Hello, world!"
Комментирование определения fromString
вызывает другую ошибку:
TestStrings.hs:11:19:
Not in scope: `fromString'
Perhaps you meant `showString' (imported from Prelude)
Если вы хотите, чтобы он работал как с строгим, так и с ленивым текстом, вы могли бы определить свой собственный класс типа IsString
и сделать оба экземпляра; класс не должен называться IsString
, только если он имеет метод fromString
.
Кроме того, слово предупреждения: в разделе руководства GHC на RebindableSyntax
не упоминается функция fromString
, а в разделе OverloadedStrings
не упоминается RebindableSyntax
. Нет причин, по которым это не должно работать, но я думаю, это означает, что это решение технически зависит от недокументированного поведения.