Haskell “MonadWidget”如何与“WidgetFor”匹配?

Haskell “MonadWidget”如何与“WidgetFor”匹配?,haskell,yesod,Haskell,Yesod,在Yesod有 defaultLayout::WidgetFor site->HandlerFor site Html setTitle::MonadWidget m=>Html=>m WidgetFor站点有一个MonadWidget实例。但是为什么defaultLayout$setTitle。。。编译 setTitle…::MonadWidget m=>m计算为任何MonadWidget m,例如,MaybeT m也有一个MonadWidget实例 我错过了什么 setTitle :: Mo

在Yesod有

defaultLayout::WidgetFor site->HandlerFor site Html setTitle::MonadWidget m=>Html=>m WidgetFor站点有一个MonadWidget实例。但是为什么defaultLayout$setTitle。。。编译

setTitle…::MonadWidget m=>m计算为任何MonadWidget m,例如,MaybeT m也有一个MonadWidget实例

我错过了什么

setTitle :: MonadWidget m => Html -> m ()
读作调用方和函数实现之间的以下契约

调用方必须选择m 调用者必须确保所选的m满足MonadWidget m约束 调用方必须传递一个Html参数 该函数将返回类型为m的值 请注意,选择m不是setTitle。该函数在OOP术语中是多态的或泛型的,可以在调用者选择的任意m处工作


由于defaultLayout需要m=WidgetFor site,GHC推断在setTitle调用中使用monad。然后输入检查。

正如您所说,对于任何MonadWidget m,它都可以计算为m。所以它还可以提供一个WidgetFor站点,这就是我们需要编译代码的地方。如果setTitle…::MonadWidget m=>m返回MonadWidget的另一个实例?我可以理解另一种情况,即,如果函数需要一个MonadWidget作为参数,而您在中传递了一个WidgetFor站点。因为WidgetFor站点有一个MonadWidget实例。但是在这里,我们有一个函数需要WidgetFor站点,我们传入任何MonadWidget。不,setTitle不返回它选择的某个实例,它可以返回调用者选择的任何实例。Haskell中的所有类型变量(如m)都是隐式量化的,这意味着调用者可以选择它们是什么。例如,Nothing::maybea a意味着在需要maybea Int的地方可以不使用任何东西,选择a=Int,但在需要maybea String的地方也可以不使用任何东西,等等。从逻辑上看,这是一个适用于所有m和某些m的区别。我想[…]这意味着调用者选择了它们是什么。这就是答案。谢谢。