0

给出这样一个简单的例子

glyphicon :: Text -> Widget
glyphicon name = toWidget [hamlet|<span class="glyphicon glyphicon-#{name}">|]

foo :: ToMarkup a => a -> Widget
foo content = toWidget [hamlet|<div class="foo">#{content}</div>|]

Yesod 中是否有内置机制可以让我同时执行foo "some text"foo (glyphicon "pencil")?我已经设法通过使用将 Text 和 Widget 都转换为 Widget 的自定义类型类来解决这个问题

class MakeWidget a where
  makeWidget :: a -> Widget

instance MakeWidget Widget where
  makeWidget = id

instance MakeWidget Text where
  makeWidget x = toWidget [hamlet|#{x}|]

glyphicon :: Text -> Widget
glyphicon name = toWidget [hamlet|<span class="glyphicon glyphicon-#{name}">|]

foo :: MakeWidget a => a -> Widget
foo content = toWidget [whamlet|<div class="foo">^{makeWidget content}</div>|]

但这感觉不对,特别是因为^{foo "hello"}由于类型不明确,我什至不能做,而是不得不做^{foo (T.pack "hello")}

有没有更好的方法将两者都嵌入Text另一个Widget内部Widget

4

1 回答 1

1

我不会走这条路,特别是因为您已经发现了类型推断问题。偶尔显式地调用 toWidget 可能是这里最好的折衷方案。

于 2015-02-14T17:32:04.387 回答