0

私は Yesod を使い始めたばかりで、すでにいくつかの興味深い結果が得られていますが、その型のいくつかを明確に理解するのに苦労しています (おそらく Template Haskell に慣れていないためです)。

hamlet スニペットを defaultLayout 関数に渡す通常の方法は、toWidget 関数を使用することです。以下の ham1 と ham2 の定義に従うと、defaultLayout 内の適切な指示はそれぞれtoWidget ham1ham2です。

私の質問:次の (動作中の) コードtoWidget ham2では、ham1 とは非常に異なる動物であるのに、命令がコンパイルされるのはなぜですか? ham1 :: t -> Text.Blaze.Internal.Markup これは、ham1 の型 ( (*) ) と ham2 の型 ( ) の両方が ToWidget クラスのインスタンスであることを意味していると思いますが、このクラスのインスタンス定義ham2 :: Widgetを読んでも、それは完全には明らかではありません。

(*)また、誰かがt -> Text.Blaze.Internal.Markupham1 よりも「より適切な」タイプのシノニムがあれば教えていただければ幸いです。

コード:

{-# 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

出力:

ここに画像の説明を入力

4

1 に答える 1

2

何が求められているのか完全にはわからないので、それがどのように機能するかを説明します。関連性があることを願っています。

defaultLayoutうまく配置するにはウィジェットが必要です…デフォルトのレイアウト。したがって、 doブロックはウィジェットをモナドに結合します。タイプチェッカーに合格するには、そのブロック内のすべての行がdoタイプである必要がありますWidget a(またはWidgetT App IO a、サイトのデータタイプは ですApp)。のインスタンスはToWidget、ウィジェットに変換できるものです。Widgets は、この型クラスのインスタンスであり、render -> Htmlモノでもあります。Htmlが の型シノニムである ことを考えるとText.Blaze.Internal.Markup、 yourham1は に渡されるのに最適な候補toWidgetです。ソース コードを参照してください。

instance render ~ RY site => ToWidget site (render -> Html) where
    toWidget x = …

(~)追加の制約を設定し、型チェッカーに (このインスタンスが既に選択された後) rendertype を持たなければならないことを伝えRY siteます。 siteファントム タイプ。システムのさまざまな部分が同じサイトに属していることを保証します。通常はApp、足場を使用している場合です。 変数を渡すRY site別の型シノニムを使用すると、次のような型になります。RYsite

Route App -> [(Text, Text)] -> Text

これは引数ham1を取るタイプです。

したがって、これらのインスタンスを使用すると、さまざまなものをウィジェットに変換できます。これには、hamlet準クォーターによって生成されるような関数が含まれますが、ここでは魔法ではありません。

于 2016-01-05T11:24:38.377 に答える