给出一个像这样的简单例子
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
?
答案 0 :(得分:1)
我不会走这条路,特别是因为您已经发现的类型推断问题。偶尔必须偶尔调用Widget可能是最好的妥协。