Как построить предварительно выбранный вариант для selectField в Yesod? - PullRequest
0 голосов
/ 16 сентября 2018

( Это спрашивалось ранее, но у него нет ответов ).

У меня есть список стран в базе данных:

share [mkPersist sqlSettings] [persistLowerCase|
Country
  name Text
  UniqueCountryName name
  deriving Show
|]

И я могу показатьформа для выбора одного из них:

countries = do
  rows <- runDB $ selectList [] [Asc CountryName]
  optionsPairs $ map (\ r -> (countryName $ entityVal r, entityKey r)) rows

surveyForm :: Html -> MForm Handler (FormResult SurveyAnswerSet, Widget)
surveyForm extra = do
  (countryR, countryV) <- mreq (selectField countries) "" Nothing

Я знаю, что должен заменить Nothing в последней строке на требуемое значение по умолчанию, но я все еще не понимаю, как это сделать.Глядя на подписи mreq и optionsPairs, я подумал, что в этом случае я должен предоставить Maybe Option стране по умолчанию, но мои попытки вызвали так многоошибки, из-за которых я, вероятно, далек от правильного ответа.

В книге «Йесод» приведен пример, который выглядит более простым, чем то, что я пытался достичь, поэтому я не уверен, как его экстраполировать.Кстати, я получаю страну по умолчанию из базы данных, поэтому мне не нужно жестко кодировать ее внутренний идентификатор:

defaultCountry = do
  row <- runDB $ getBy $ UniqueCountryName $ countryName "United States"
  (countryName $ entityVal row, entityKey row)

Когда я передаю ее в качестве аргумента mreq, я получаю следующие ошибки:

Не удалось сопоставить тип '(,) Text' с 'HandlerFor site' Ожидаемый тип: HandlerFor site (ключевая запись) Фактический тип: (Text, Key record)

Это последняя строка функции defaultContry ((countryName $ entityVal row, entityKey row)).Я понимаю, что я должен взять Key record из пары и вернуть его в HandlerFor site, но в то же время я также получаю:

Не удалось найти ожидаемый тип 'Возможно (ключевая страна) 'с действительным типом' HandlerFor site0 (Key record0) '

В строке (countryR, countryV) <- mreq (selectField countries) "" defaultCountry.Я интерпретирую это как «вы передаете мне HandlerFor site0 (Key record0), но я принимаю только Maybe (Key Country), что кажется конфликтующим с первой ошибкой ...

В строке (countryName $ entityVal row, entityKey row) я также вижу:

Не удалось сопоставить ожидаемый тип «Страна сущности» с фактическим типом «Возможно (Страна сущности)»

в аргументе row. Я понимаю, что должен извлечь Entity Country из Maybe, но если я сопоставлю шаблон и передам только Entity Country (т.е.: Just (Entity countryId country) -> (countryName $ entityVal (Entity countryId country), entityKey (Entity countryId country)), я все равно получу первую ошибку.

Заранее спасибо.

1 Ответ

0 голосов
/ 17 сентября 2018

Хорошо, это похоже на несколько ошибок типа.Первый

Невозможно сопоставить тип '(,) Text' с 'HandlerFor site' Ожидаемый тип: HandlerFor site (ключевая запись) Фактический тип: (Text, Key record)

происходит из-за неиспользования return в нотации do для поднятия значения в монаду:

defaultCountry :: HandlerFor site (Text, Key record)
defaultCountry = do
  row <- runDB $ getBy $ UniqueCountryName $ countryName "United States"
  return (countryName $ entityVal row, entityKey row)

Ошибка row

Не удалосьНе соответствует ожидаемый тип «Страна сущности» фактическому типу «Возможно (Страна сущности)»

, потому что это Maybe, поэтому давайте исправим это

defaultCountry :: HandlerFor site (Text, Key record)
defaultCountry = do
  Just row <- runDB $ getBy $ UniqueCountryName $ countryName "United States"
  return (countryName $ entityVal row, entityKey row)

Сейчасчто defaultCountry хорошая монада, вы должны иметь возможность использовать ее в другом коде.Но будьте осторожны с этой третьей ошибкой

Не удалось сопоставить ожидаемый тип 'Maybe (Key Country)' с фактическим типом 'HandlerFor site0 (Key record0)'

Youнужно развернуть значение из монады HandlerFor и перемотать его в Maybe

surveyForm :: Html -> MForm Handler (FormResult SurveyAnswerSet, Widget)
surveyForm extra = do
  (defaultName, defaultKey) <- defaultCountry -- (defaultName, defaultKey) :: (Text, Key record)
  (countryR, countryV) <- mreq (selectField countries) "" (Just defaultKey)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...