Two things I can't figure out:
1) Without {-# LANGUAGE OverloadedStrings #-}
none of the typical code, where pure strings are passed as an arguments for attributes, works; however everything fine as long as that instruction is there. What does it do in this particular case and how safe is it to use in a production code?
2) Following piece of code: (toHtml $ "<script ... ></script>")
fails with something I don't quite understand:
Ambiguous type variable ‘a0’ arising from the literal ... prevents the constraint ‘(Data.String.IsString a0)’ from being solved. Probable fix: use a type annotation to specify what ‘a0’ should be. These potential instances exist: instance Data.String.IsString H.AttributeValue -- Defined in ‘blaze-markup-0.8.2.1:Text.Blaze.Internal’ instance Data.String.IsString H.Tag -- Defined in ‘blaze-markup-0.8.2.1:Text.Blaze.Internal’ instance a ~ Char => Data.String.IsString [a] -- Defined in ‘Data.String’ ...plus 10 instances involving out-of-scope types
In standard Haskell, a string literal like "foo"
is always parsed into a value of type String = [Char]
. Blaze doesn't use actual String
values in most places, instead using its own types like AttributeValue
for each semantically different thing. This means that in standard Haskell, without OverloadedStrings
, it is impossible to pass string literals to many Blaze functions which expect AttributeValue
s, Tag
s, etc. When you set -XOverloadedStrings
, GHC will allow a string literal to have type Data.String.IsString p => p
instead of String
, so you can use a string literal anywhere that some type which has an instance of IsString
is expected. This is used by all the "standard" Blaze code. OverloadedStrings
is a fairly simple extension---it is basically doing for string literals what Num
does for integer literals---and I'm not aware of any large amount of controversy around it. I think that it should be safe for use in production code, and several production codebases use it.
This error message is due to the fact that toHtml
is universally quantified over the type of its first argument, with some constraints: toHtml :: ToMarkup a => a -> Html
, and---with OverloadedStrings
---the type of a string is also a type variable. Basically, GHC knows that the type of the string literal, which will be passed into toHtml
needs to be some type, and that type needs to have instances for ToMarkup
and IsString
, but it doesn't have any way to be sure what that type should be! In this case, it looks like you are probably looking for the string literal to actually have type String
here, which you can get by manually annotating the literal: toHtml ("foo" :: String)
, or by using -XTypeApplications
: toHtml @String "foo"
.