I am currently in the process of rewriting an HTML file in Lucid for use with a Spock web server. However, for some reason this particular snippet gives me an error:
sidebar :: Html ()
sidebar = do
  nav_ [id_ "sidebar"] $ do
    div [class_ "sidebar-header"] $
      h3_ "Sidebar"
    div [class_ "list-group"] $ do
      a_ [href_ "#", class_ "menuItem list-group-item rounded-0"] "Item 1"
      a_ [href_ "#", class_ "menuItem list-group-item rounded-0"] "Item 2"
Namely, the error is:
Couldn't match type `[Attribute]'
               with `HtmlT Data.Functor.Identity.Identity ()'
  arising from a use of `nav_'
I noticed that removing the div and just having the h3 fixes the problem, but that is not what I want. I did some googling to try to find the issue, but from what I could see the library does not have that many examples online that I could try to look at. Stackoverflow and Reddit searches did not reveal anything either.
This is my first actual project where I have used Lucid, so it is entirely possible that there is an obvious blunder somewhere.
 
                        
The problem is the use of
div(integer division) instead ofdiv_(HTML element).The type error is slightly bizarre, but arises from how the type checker tries to infer a type for the whole expression.
class_has typeThus
[class_ "list-group"] :: [Attribute]. That's easy.divhas typeThere is an
Integralconstraint, but more importantly, both input types and the result type must be the same.In an expression like
the type checker concludes that
[class_ "list-group"],do ..., and the wholediv ... ...expression have the same type.We know the first type, so we conclude
do { a_ ...; a_ ... } :: [Attribute]anddiv [...] $ do ... :: [Attribute].This use of
divis the last statement in adoblock, which means its type is also the type of the wholedoexpression.I'm a bit fuzzy on the next part, but I think the type checker looks at
and
and the available
Terminstances, and concludes that because the declared result type issidebar :: Html (), the second argument tonav_(thedoblock) must also have typeHtml (), which is an alias forHtmlT Identity ().Now we have a conflict: The declared type signature says the second argument of
nav_must be aHtmlT Identity (), but the inferred type is[Attribute].At this point the type checker just gives up and reports the confusing problem to the user.