清醒的导航元素给出有关属性列表的错误

时间:2019-06-04 15:12:23

标签: haskell haskell-lucid

我目前正在用Lucid重写HTML文件,以用于Spock Web服务器。但是,由于某些原因,这个特定代码段给了我一个错误:

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"

即,错误是:

Couldn't match type `[Attribute]'
               with `HtmlT Data.Functor.Identity.Identity ()'
  arising from a use of `nav_'

我注意到删除div并仅使用h3可以解决问题,但这不是我想要的。我进行了一些谷歌搜索以查找问题,但是从我可以看到的事实来看,该图书馆没有可供尝试查看的在线示例。 Stackoverflow和Reddit搜索也没有发现任何内容。

这是我使用Lucid的第一个实际项目,因此完全有可能在某个地方出现明显的错误。

1 个答案:

答案 0 :(得分:0)

问题是使用div(整数除法)而不是div_(HTML元素)。

类型错误有些奇怪,但这是由于类型检查器试图为整个表达式推断类型而引起的。

class_具有类型

class_ :: Text -> Attribute

因此[class_ "list-group"] :: [Attribute]。很简单。

div具有类型

div :: Integral a => a -> a -> a

有一个Integral约束,但更重要的是,输入类型和结果类型必须相同。

在类似

的表达式中
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"

类型检查器得出结论,[class_ "list-group"]do ...和整个div ... ...表达式具有相同的类型。

我们知道第一种类型,因此我们得出do { a_ ...; a_ ... } :: [Attribute]div [...] $ do ... :: [Attribute]的结论。

这种div的使用是do块中的最后一条语句,这意味着它的类型也是整个do表达式的类型。

下一部分我有点模糊,但是我认为类型检查器会关注

nav_ :: Term arg result => arg -> result

class Term arg result | result -> arg

和可用的Term实例,并得出结论,由于声明的结果类型为sidebar :: Html ()nav_的第二个参数(do块)也必须具有类型Html (),它是HtmlT Identity ()的别名。

现在我们有一个冲突:声明的类型签名说nav_的第二个参数必须是HtmlT Identity (),但是推断出的类型是[Attribute]

这时,类型检查器将放弃并向用户报告令人困惑的问题。