-
OverloadedStrings -
- Начиная с:
-
6.8.1
Включает перегруженные строковые литералы (например, строковые литералы, преобразуемые в синтаксис без сахара с помощью класса
IsString).
GHC поддерживает перегруженные строковые литералы. Обычно строковый литерал имеет тип String, но при включённых перегруженных строковых литералах (с помощью OverloadedStrings) строковый литерал имеет тип (IsString a) => a.
Это означает, что обычный синтаксис строк можно использовать, например, для ByteString, Text и других вариантов строкоподобных типов. Строковые литералы ведут себя почти так же, как целочисленные литералы: их можно использовать как в выражениях, так и в образцах. При использовании в образце литерал заменяется проверкой на равенство, так же как и целочисленный литерал.
Класс IsString определяется следующим образом:
class IsString a where
fromString :: String -> a
Единственный предопределённый экземпляр — очевидный, позволяющий строкам работать как обычно:
instance IsString [Char] where
fromString cs = cs
Класс IsString по умолчанию не входит в область видимости. Если вы хотите явно упомянуть его (например, чтобы объявить для него экземпляр), его можно импортировать из модуля Data.String.
Включение OverloadedStrings расширяет механизм вывода типов по умолчанию в Haskell — вывод типов классов по умолчанию — следующим образом:
- Вывод типов по умолчанию применяется, когда все неразрешённые ограничения относятся к стандартным классам или
IsString, и хотя бы одно из них относится к числовому классу илиIsString. -
-
String is added to the end of the standard list of types which are tried -
при выводе типов по умолчанию объявления
defaultрасширяются и допускают любой тип, являющийся экземпляромIsString.
-
Так, например, выражение length "foo" приводит к неоднозначному использованию IsString a0, которое в соответствии с приведёнными выше правилами будет сведено по умолчанию к String.
Пользователи могут дополнительно включить ExtendedDefaultRules, которая смягчает условие, запрещающее выводить по умолчанию типовую переменную, выступающую аргументом нестандартного или неунарного класса.
Пользователям, которые хотят, чтобы для строковых литералов по умолчанию выбирались другие строкоподобные типы, например Text или ByteString, рекомендуется задать собственные объявления типов по умолчанию, например:
default (Int, Double, Text)
или, используя NamedDefaults:
default IsString (Text)
Небольшой пример:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.String( IsString(..) )
newtype MyString = MyString String deriving (Eq, Show)
instance IsString MyString where
fromString = MyString
greet :: MyString -> MyString
greet "hello" = "world"
greet other = other
main = do
print $ greet "hello"
print $ greet "fool"
Обратите внимание, что для работы сопоставления с образцом необходимо выводить Eq, поскольку оно преобразуется в сравнение на равенство.