我刚开始玩 Yesod,虽然我已经可以得到一些有趣的结果,但我很难清楚地理解它的一些类型(可能是因为我不熟悉 Template Haskell)。
将hamlet 片段传递给 defaultLayout 函数的常用方法是通过 toWidget 函数。因此,按照下面 ham1 和 ham2 的定义,defaultLayout 中的正确指令分别是toWidget ham1
和ham2
。
我的问题:在以下(工作)代码中,为什么指令toWidget ham2
会编译,而它与 ham1 是完全不同的动物?我猜这意味着 ham1 的类型 ( ham1 :: t -> Text.Blaze.Internal.Markup
(*) ) 和 ham2 的类型 ( ham2 :: Widget
) 都是 ToWidget 类的实例,但在阅读此类的实例定义时这对我来说并不完全明显。
(*)另外,如果有人能告诉我是否有比t -> Text.Blaze.Internal.Markup
ham1 更好的类型同义词,那就太好了。
代码:
{-# 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
输出 :