【发布时间】:2016-01-05 10:39:15
【问题描述】:
我刚开始玩 Yesod,虽然我已经可以得到一些有趣的结果,但我很难清楚地理解它的一些类型(可能是因为我不熟悉 Template Haskell)。
usual way 将 hamlet sn-p 传递给 defaultLayout 函数是通过 toWidget 函数。所以按照下面对ham1和ham2的定义,defaultLayout中正确的指令分别是toWidget ham1和ham2。
我的问题:在下面的(工作)代码中,为什么指令toWidget ham2 编译,而它是与ham1 完全不同的动物?我想这意味着 ham1 的类型 (ham1 :: t -> Text.Blaze.Internal.Markup (*)) 和 ham2 的类型 (ham2 :: Widget) 都是 ToWidget 类的实例,但在阅读此 @987654322 时这对我来说并不完全明显@。
(*)另外,如果有人能告诉我ham1是否有比t -> Text.Blaze.Internal.Markup“更好”的类型同义词,那就太好了。
代码:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module Main where
import Yesod
import Text.Blaze.Internal (Markup)
data App = App
instance Yesod App
mkYesod "App" [parseRoutes|
/ HomeR GET
|]
getHomeR :: Handler Html
getHomeR = defaultLayout $ do
setTitle "Some Title"
toWidget ham1 -- usual way to produce a Widget from hamlet snippet
toWidget ham2 -- ??
ham2 -- already of type Widget
ham1 :: t -> Text.Blaze.Internal.Markup -- explicit signature for reference only
ham1 = [hamlet|
<h1> 1) Hello
<h2> World!
|]
ham2 :: Widget
ham2 =
toWidget [hamlet|
<h1> 2) Hello
<h2> World!
|]
main :: IO ()
main = do
warp 3000 App
输出:
【问题讨论】: