如何在Yesod中将Text和Widget都嵌入到另一个Widget中



给出一个类似的简单示例

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")}

有没有更好的方法将TextWidget嵌入另一个Widget中?

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

最新更新