Yesod fvInput не может сопоставить «App» с «Auth»

Я пытаюсь написать пользовательскую регистрационную форму Yesod. Проблема, с которой я сталкиваюсь, заключается в том, что когда он попадает в fvInput, кажется, что он использует приложение вместо аутентификации. Я не совсем уверен, как это должно быть обработано, и я не могу найти терминологию для этого. Я пробовал поднимать по-разному в форме, и я могу заставить его выдавать только разные ошибки. Кроме того, единственный раз, когда эта ошибка выдается, - это если у меня есть строка fvInput, но если я удалю ее, ошибка не будет выдана, и она скомпилируется правильно.

Код:

registrationForm :: Html -> MForm (HandlerT Auth (HandlerT App IO)) (FormResult UserForm, Widget)
registrationForm extra = do
    (emailRes, emailView) <- mreq textField "" Nothing
    let userRes = UserForm <$> emailRes
    let widget = do
        [whamlet|
            #{extra}
            ^{fvInput emailView}
            <input type=Submit value="Registration">
        |]

    return (userRes, widget)

Ошибка:

Foundation.hs:169:30:
    Couldn't match type ‘App’ with ‘Auth’
    In the second argument of ‘(GHC.Base..)’, namely ‘toWidget’
    In the expression: asWidgetT GHC.Base.. toWidget
    In a stmt of a 'do' block:
      (asWidgetT GHC.Base.. toWidget) (fvInput emailView)

Спасибо заранее за любую помощь!

  • Редактировать

Ошибка с подъемом перед mreq:

Foundation.hs:166:49:
   Couldn't match type ‘HandlerT Auth (HandlerT App IO)’
               with ‘transformers-0.4.2.0:Control.Monad.Trans.RWS.Lazy.RWST
                       (Maybe (Env, FileEnv), HandlerSite m0, [Lang]) Enctype Ints m0’
    Expected type: HandlerT
                 Auth (HandlerT App IO) (FormResult Text, FieldView App)
      Actual type: MForm m0 (FormResult Text, FieldView App)
    In the second argument of ‘($)’, namely ‘mreq textField "" Nothing’
    In a stmt of a 'do' block:
      (emailRes, emailView) <- lift $ mreq textField "" Nothing

person Lethjakman    schedule 26.01.2016    source источник


Ответы (1)


Ваш возвращаемый тип Widget на самом деле:

WidgetT App IO ()

Таким образом, существует несоответствие между Widget (которая живет только в App) и emailView (которая живет в поднятой монаде HandlerT Auth (HandlerT App IO)).

Чтобы решить эту проблему:

  1. Измените тип подписи на registrationForm :: Html -> MForm (HandlerT App IO) (FormResult UserForm, Widget)
  2. На месте использования вам, скорее всего, потребуется использовать lift, но после того, как вы уже вызвали соответствующую run функцию для формы
person Michael Snoyman    schedule 26.01.2016
comment
Я пробовал это в какой-то момент. Я думал, что это неправильно, потому что выдавало другую ошибку. Я обновлю сообщение выше, чтобы добавить другую ошибку с лифтом. Спасибо за вашу помощь! - person Lethjakman; 27.01.2016
comment
Моя ошибка, лифт не тот. Я обновлю ответ. - person Michael Snoyman; 27.01.2016
comment
Вот оно. Благодарю вас! - person Lethjakman; 29.01.2016