0

之前有人问过,但没有答案)。

我在数据库中有一个国家列表:

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所需的默认值替换最后一行中的,但我仍然不知道该怎么做。看着mreqoptionsPairs签名,我的想法是,在这种情况下,我应该提供Maybe Option默认国家/地区,但我的尝试引发了如此多的类型错误,可能我离正确答案还很远。

Yesod 书有一个示例,使用似乎比我试图实现的更简单,所以我不知道如何推断它。

顺便说一句,我从数据库中获取了默认国家,所以我不需要硬编码它的内部 id:

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

当我将它作为参数传递给mreq我时,会出现以下错误:

无法将类型 '(,) Text' 与 'HandlerFor site' 匹配 预期类型:HandlerFor 站点(关键记录) 实际类型:(文本,关键记录)

这是defaultContry函数 ( (countryName $ entityVal row, entityKey row)) 的最后一行。我知道我应该Key record从这对中取出并返回,HandlerFor site但同时我也得到:

无法将预期类型 'Maybe (Key Country)' 与实际类型 'HandlerFor site0 (Key record0)' 匹配</p>

(countryR, countryV) <- mreq (selectField countries) "" defaultCountry在行。我将此解释为“您传递给我一个HandlerFor site0 (Key record0)但我只接受Maybe (Key Country)似乎与第一个错误相冲突的...

在这一(countryName $ entityVal row, entityKey row)行中,我还看到:

无法将预期类型“实体国家”与实际类型“可能(实体国家)”匹配</p>

row论据中。我知道我应该从中提取,Entity CountryMaybe如果我模式匹配并仅传递Entity Country(ie:)Just (Entity countryId country) -> (countryName $ entityVal (Entity countryId country), entityKey (Entity countryId country)我仍然会收到第一个错误。

提前致谢。

4

1 回答 1

1

好吧,这看起来像一些类型错误。首先

无法将类型 '(,) Text' 与 'HandlerFor site' 匹配 预期类型:HandlerFor 站点(关键记录) 实际类型:(文本,关键记录)

来自于没有return在你的do符号中使用来提升 monad 的价值:

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

上的错误row

无法将预期类型“实体国家”与实际类型“可能(实体国家)”匹配</p>

是因为它是 a Maybe,所以让我们更正一下

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

现在这defaultCountry是一个很好的 monad,您应该可以在其他代码中使用它。但要小心第三个错误

无法将预期类型 'Maybe (Key Country)' 与实际类型 'HandlerFor site0 (Key record0)' 匹配</p>

您需要从HandlerFormonad 中解开值,并将其重新包装在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)
于 2018-09-17T12:54:27.957 回答