`MonadWidget` 如何适应 `WidgetFor`?
How does `MonadWidget` fit to `WidgetFor`?
Yesod 有
defaultLayout :: WidgetFor site () -> HandlerFor site Html
setTitle :: MonadWidget m => Html => m ()
WidgetFor site
有一个 MonadWidget
的实例。但是为什么 defaultLayout $ setTitle "..."
可以编译?
setTitle "..." :: MonadWidget m => m ()
计算为 any MonadWidget m
(例如 MaybeT m
也有一个 MonadWidget
的实例)。
我在这里错过了什么?
setTitle :: MonadWidget m => Html -> m ()
读作调用者和函数实现之间的以下契约
- 来电者必须选择
m
- 调用者必须确保选择的
m
满足MonadWidget m
约束
- 调用方必须传递一个
Html
参数
- 该函数将 return 类型为
m ()
的值
注意不是setTitle
选择m
。该函数是多态的(或 OOP 术语中的 "generic"),并且可以在调用者选择的任何 m
上工作。
由于 defaultLayout
需要 m = WidgetFor site
,GHC 推断在 setTitle
调用中使用了 monad。然后输入所有内容。
Yesod 有
defaultLayout :: WidgetFor site () -> HandlerFor site Html
setTitle :: MonadWidget m => Html => m ()
WidgetFor site
有一个 MonadWidget
的实例。但是为什么 defaultLayout $ setTitle "..."
可以编译?
setTitle "..." :: MonadWidget m => m ()
计算为 any MonadWidget m
(例如 MaybeT m
也有一个 MonadWidget
的实例)。
我在这里错过了什么?
setTitle :: MonadWidget m => Html -> m ()
读作调用者和函数实现之间的以下契约
- 来电者必须选择
m
- 调用者必须确保选择的
m
满足MonadWidget m
约束 - 调用方必须传递一个
Html
参数 - 该函数将 return 类型为
m ()
的值
注意不是setTitle
选择m
。该函数是多态的(或 OOP 术语中的 "generic"),并且可以在调用者选择的任何 m
上工作。
由于 defaultLayout
需要 m = WidgetFor site
,GHC 推断在 setTitle
调用中使用了 monad。然后输入所有内容。