Question

I'm trying to extend Happstack crash course blog with some additional functionality: displaying a list of all tags on home page.

My blog record looks like this:

data Blog = Blog
    { nextPostId :: PostId
    , posts      :: IxSet Post
    , allTags    :: [Text] 
    }
    deriving (Data, Typeable)

I get blog post by id in the following way (copypasted from crash course):

-- 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
        ...

And it works alright.

When I try to do querying of all tags in the similar way:

-- Models.hs 

getTags :: Query Blog [Text]
getTags = 
    do Blog{..} <- ask
       return allTags

-- Controller.hs

serveTags :: AcidState Blog -> [Text]
serveTags acid = query' acid GetTags

It won't work. The error stack trace is:

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

I can't figure out why the return type of query' is [EventResult GetTags], while it should be [Text].

What is the reason for this error? Is there a way to fix it?

Was it helpful?

Solution

The problem is your type signature on the serveTags function, it should be monadic:

serveTags :: MonadIO m => AcidState Blog -> m [Text]
serveTags acid = query' acid GetTags

EventResult is a type family that here resolves to [Text]. Since query' is monadic, your type signature got resolved to the list monad, i.e. m Text where the m is the list monad, thus the confusing error message.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top