2

Given:

import Lucid
import Lucid.Base

mainPage :: Html ()
mainPage = div_ (p_ "hello")

I get the following compile-time error:

/Users/kevinmeredith/Workspace/my-project/src/Lib.hs:9:18: error:
    • Couldn't match type ‘HtmlT Data.Functor.Identity.Identity ()’
                     with ‘[Char]’
        arising from a functional dependency between:
          constraint ‘Term [Char] (HtmlT Data.Functor.Identity.Identity ())’
            arising from a use of ‘p_’
          instance ‘Term (HtmlT m a) (HtmlT m a)’ at <no location info>
    • In the first argument of ‘div_’, namely ‘(p_ "hello")’
      In the expression: div_ (p_ "hello")
      In an equation for ‘mainPage’: mainPage = div_ (p_ "hello")

How can I fix this compile-time error please?

Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384

2 Answers2

3

As is written in the documentation:

Intro

(..)

For GHCi:

:set -XOverloadedStrings -XExtendedDefaultRules@
import Lucid

In a module: {-# LANGUAGE OverloadedStrings, ExtendedDefaultRules #-}

(..)

So you need to turn on the OverloadedStrings and ExtendedDefaultRules extensions.

You can do this by compiling with:

ghc -XOverloadedStrings -XExtendedDefaultRules file.hs

But perhaps more convenient is to turn the extensions on in the header of the file:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExtendedDefaultRules #-}

import Lucid
import Lucid.Base

mainPage :: Html ()
mainPage = div_ (p_ "hello")

Like the compiler says in the error message, p_ and div_ do not expect Strings, but a HtmlT Data.Functor.Identity.Identity () type (some sort of string). This type is however a member of the IsString typeclass, so it can be seen as "string-like" types, and has an implementation [source code]:

instance (Monad m,a ~ ()) => IsString (HtmlT m a) where
  fromString = toHtml

The reason this happens is because you can add HTML characters, in which case (p_ "<foo>") would look like: <p><foo></p>. But this is quite unsafe. By first processing it through toHtml, the result will be <p>&lt;foo&gt;</p>.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
0

If you're not using literal strings, you can explicitly call the fromString method:

import Lucid
import Lucid.Base
import Data.String

v = "hello"

mainPage :: Html ()
mainPage = div_ (p_ $ fromString v)
Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286