Как `MonadWidget` подходит для` WidgetFor`? - PullRequest
2 голосов
/ 30 июня 2019

В есод есть

defaultLayout :: WidgetFor site () -> HandlerFor site Html

setTitle :: MonadWidget m => Html => m ()

WidgetFor site имеет экземпляр MonadWidget. Но почему defaultLayout $ setTitle "..." компилируется?

setTitle "..." :: MonadWidget m => m () оценивается как любой MonadWidget m (например, MaybeT m также имеет экземпляр MonadWidget).

Что мне здесь не хватает?

1 Ответ

4 голосов
/ 30 июня 2019
setTitle :: MonadWidget m => Html -> m ()

читается как следующий контракт между вызывающей стороной и реализацией функции

  • вызывающий должен выбрать m
  • вызывающий должен убедиться, что выбранный m удовлетворяет ограничению MonadWidget m
  • вызывающая сторона должна передать Html аргумент
  • функция вернет значение типа m ()

Обратите внимание, что setTitle нельзя выбирать m. Эта функция полиморфна (или «универсальна» в языке ООП) и работает на любом m, который выбирает вызывающий.

Поскольку defaultLayout требует m = WidgetFor site, GHC определяет, какую монаду следует использовать при вызове setTitle. Затем все проверяет тип.

...