Неожиданный тип возврата запроса кислотного состояния (Happstack)
Я пытаюсь расширить блог ускоренного курса Happstack с помощью некоторых дополнительных функций: отображение списка всех тегов на домашней странице.
Моя запись в блоге выглядит так:
data Blog = Blog
{ nextPostId :: PostId
, posts :: IxSet Post
, allTags :: [Text]
}
deriving (Data, Typeable)
Я получаю сообщение в блоге по идентификатору следующим образом (скопировано из ускоренного курса):
-- Models.hs
postById :: PostId -> Query Blog (Maybe Post)
postById pid =
do Blog{..} <- ask
return $ getOne $ posts @= pid
-- Controller.hs
viewPage :: AcidState Blog -> ServerPart Response
viewPage acid =
do pid <- PostId <$> lookRead "id"
mPost <- query' acid (PostById pid)
...
-- mPost has type Maybe Post here
...
И это работает хорошо.
Когда я пытаюсь сделать запрос всех тегов аналогичным образом:
-- Models.hs
getTags :: Query Blog [Text]
getTags =
do Blog{..} <- ask
return allTags
-- Controller.hs
serveTags :: AcidState Blog -> [Text]
serveTags acid = query' acid GetTags
Это не сработает. Трассировка стека ошибок:
Blog/Controllers.hs:154:18:
Couldn't match type `[Text]' with `Text'
Expected type: [Text]
Actual type: [acid-state-0.8.1:Data.Acid.Common.EventResult
GetTags]
In the return type of a call of query'
In the expression: query' acid GetTags
Я не могу понять, почему возвращаемый тип query'
является [EventResult GetTags]
в то время как это должно быть [Text]
,
В чем причина этой ошибки? Есть ли способ это исправить?
1 ответ
Проблема в том, что ваша подпись типа на serveTags
Функция должна быть монадической:
serveTags :: MonadIO m => AcidState Blog -> m [Text]
serveTags acid = query' acid GetTags
EventResult
это семейство типов, которое здесь разрешает [Text]
, поскольку query'
является монадическим, подпись вашего типа разрешена в монаду списка, т.е. m Text
где m
это монада списка, таким образом, сбивающее с толку сообщение об ошибке.