Почему одно использование toWidget работает, а другое нет - PullRequest
2 голосов
/ 18 января 2012

Я попытался изменить проект Yesod, и натолкнулся на странную ошибку. Сначала я представлю код рабочей формы и сломанный код с сообщением об ошибке.

type PForm x = ProductConfig -> Html -> MForm ReScheduler ReScheduler (FormResult x, Widget)

рабочий код следующий

productForm :: PForm SelectedProduct
productForm config extra = do
   let pInfo' = pInfo config
       aDays' = aDays config
       products = (catMaybes . pNametoText) pInfo'
       versions' = map consVersionPair pInfo'
   productInfo <- mapM generateSelectFields versions'
   (dateRes, dateView) <- mreq (selectField aDays') "placeHolder" Nothing
   (mailRes, mailView) <- mreq emailField "E-Mail Address" Nothing
   (noteRes, noteView) <- mreq textareaField
                               "Notes"
                               Nothing
   let productVersion = reduceFormResults $
                        map flagSelected $
                        map fst productInfo

       versionViews = map snd productInfo
   let widget =
          toWidget $(widgetFile "firmware") :: Widget


   return (makeSelected productVersion dateRes mailRes noteRes, widget)

Приведенный выше код работает нормально. Вот сломанный код, за которым следуют ошибка и некоторые наблюдения.

type RForm x = [KeyJobPair] -> Html -> MForm ReScheduler ReScheduler (FormResult x, Widget)

statusForm :: RForm ModData
statusForm kjPairs extra = do
--    let bPairs = buttonPairs kjPairs
--        statusPairs = map (pack . show &&& id) $
--                      ([minBound .. maxBound] :: [Status])
--    (jobRes,jobView) <- mreq (radioField bPairs) "Scheduled Jobs" Nothing
--    (mailRes, mailView) <- mreq emailField "E-Mail Address" Nothing
--    (noteRes, noteView) <- mreq textareaField "Notes" Nothing
--    (statusRes, statusView) <- mreq (selectField statusPairs) "Status" Nothing
--    let widget = toWidget [hamlet|<p> testing |]
    let widget = (toWidget $(widgetFile "status" )) :: Widget
    return (ModData <$> undefined <*> undefined <*> undefined, widget)


Handler/Manager.hs:109:19:
 No instance for (ToWidget
               ReScheduler ReScheduler (GGWidget master0 m0 ()))
  arising from a use of `toWidget'
Possible fix:
  add an instance declaration for
  (ToWidget ReScheduler ReScheduler (GGWidget master0 m0 ()))
In the expression: (toWidget ($(widgetFile "status"))) :: Widget
In an equation for `widget':
    widget = (toWidget ($(widgetFile "status"))) :: Widget
In the expression:
  do { let widget = ...;
       return
         (ModData <$> undefined <*> undefined <*> undefined, widget) }

Обратите внимание на закомментированный код хамлета. Это хорошо компилируется. Это приводит меня к мысли, что проблема заключается в widgetFile, а не toWidget. Я заметил в блоге Yesod, что иногда widgetFile хочет явно подпись типа :: Widget. Я не смог заставить это работать. Может быть, это просто проблема синтаксиса. Обратная связь будет приветствоваться. В то же время я могу просто использовать твердо закодированный Гамлет.

1 Ответ

2 голосов
/ 18 января 2012

Это была проблема с синтаксисом. Это был вопрос правильного размещения подписи типа.

let widget = toWidget ($(widgetFile "status") :: Widget)

Это правильно.

...