我目前正在用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的第一个实际项目,因此完全有可能在某个地方出现明显的错误。
答案 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]
。
这时,类型检查器将放弃并向用户报告令人困惑的问题。