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 ответ

Решение
  1. В стандартном Haskell строковый литерал похож на "foo" всегда разбирается в значение типа String = [Char], Blaze не использует фактический String значения в большинстве мест, вместо этого используя свои собственные типы, такие как AttributeValue для каждой семантически разные вещи. Это означает, что в стандартном Haskell, без OverloadedStrings, невозможно передать строковые литералы многим функциям Blaze, которые ожидают AttributeValues, Tags и т. д. При установке -XOverloadedStrings, GHC позволит строковому литералу иметь тип Data.String.IsString p => p вместо String, так что вы можете использовать строковый литерал в любом месте, какой-то тип, который имеет экземпляр IsString ожидается. Это используется всеми "стандартными" кодами Blaze. OverloadedStrings это довольно простое расширение --- это в основном делает для строковых литералов, что Num делает для целочисленных литералов --- и я не знаю ни о каком большом количестве противоречия вокруг этого. Я думаю, что он должен быть безопасным для использования в производственном коде, и несколько производственных кодовых баз используют его.

  2. Это сообщение об ошибке связано с тем, что toHtml универсально определяется по типу своего первого аргумента с некоторыми ограничениями: toHtml :: ToMarkup a => a -> Html, и с OverloadedStrings--- тип строки также является переменной типа. По сути, GHC знает тип строкового литерала, который будет передан в toHtml должен быть некоторого типа, и этот тип должен иметь экземпляры для ToMarkup а также IsString, но у него нет никакого способа быть уверенным, каким должен быть этот тип! В этом случае, похоже, вы ищете строковый литерал, который на самом деле имеет тип String здесь, который вы можете получить, вручную пометив литерал: toHtml ("foo" :: String)или с помощью -XTypeApplications: toHtml @String "foo",

Другие вопросы по тегам