blaze-html, Haskell, правильное использование toHtml?
Две вещи, которые я не могу понять:
1) Без {-# LANGUAGE OverloadedStrings #-}
ни один из типичного кода, где чистые строки передаются в качестве аргументов для атрибутов, не работает; Однако все хорошо, пока эта инструкция есть. Что он делает в данном конкретном случае и насколько безопасно его использовать в рабочем коде?
2) Следующий кусок кода: (toHtml $ "<script ... ></script>")
терпит неудачу с чем-то, что я не совсем понимаю:
Неопределенная переменная типа 'a0', возникающая из литерала... предотвращает решение ограничения (Data.String.IsString a0) '. Возможное исправление: используйте аннотацию типа, чтобы указать, каким должно быть "a0". Существуют следующие потенциальные экземпляры: экземпляр Data.String.IsString H.AttributeValue - определен в "blaze-markup-0.8.2.1:Text.Blaze.Internal" экземпляр Data.String.IsString H.Tag - определен в "blaze-markup" -0.8.2.1: Text.Blaze.Internal 'экземпляр a ~ Char => Data.String.IsString [a] - определен в "Data.String"... плюс 10 экземпляров, включающих типы вне области видимости
1 ответ
В стандартном Haskell строковый литерал похож на
"foo"
всегда разбирается в значение типаString = [Char]
, Blaze не использует фактическийString
значения в большинстве мест, вместо этого используя свои собственные типы, такие какAttributeValue
для каждой семантически разные вещи. Это означает, что в стандартном Haskell, безOverloadedStrings
, невозможно передать строковые литералы многим функциям Blaze, которые ожидаютAttributeValue
s,Tag
s и т. д. При установке-XOverloadedStrings
, GHC позволит строковому литералу иметь типData.String.IsString p => p
вместоString
, так что вы можете использовать строковый литерал в любом месте, какой-то тип, который имеет экземплярIsString
ожидается. Это используется всеми "стандартными" кодами Blaze.OverloadedStrings
это довольно простое расширение --- это в основном делает для строковых литералов, чтоNum
делает для целочисленных литералов --- и я не знаю ни о каком большом количестве противоречия вокруг этого. Я думаю, что он должен быть безопасным для использования в производственном коде, и несколько производственных кодовых баз используют его.Это сообщение об ошибке связано с тем, что
toHtml
универсально определяется по типу своего первого аргумента с некоторыми ограничениями:toHtml :: ToMarkup a => a -> Html
, и сOverloadedStrings
--- тип строки также является переменной типа. По сути, GHC знает тип строкового литерала, который будет передан вtoHtml
должен быть некоторого типа, и этот тип должен иметь экземпляры дляToMarkup
а такжеIsString
, но у него нет никакого способа быть уверенным, каким должен быть этот тип! В этом случае, похоже, вы ищете строковый литерал, который на самом деле имеет типString
здесь, который вы можете получить, вручную пометив литерал:toHtml ("foo" :: String)
или с помощью-XTypeApplications
:toHtml @String "foo"
,