3

我正在尝试使用selectRepYesod 1.2 中的新功能,但我无法让 json 响应正常工作。

instance ToJSON (Entity Feed) where
    toJSON (Entity uid (Feed url lastUpdated)) = object 
        [ "id" .= uid
        , "url" .= url
        , "lastUpdated" .= lastUpdated
        ]

getFeedByIdR :: FeedId -> Handler TypedContent
getFeedByIdR feedId = do
    feed <- runDB $ get404 feedId
    selectRep $ do
        provideRep $ return $ toJSON (Entity feedId feed)

我从上面的代码中得到的错误是

Handler/Feed.hs:23:31:
    Overlapping instances for ToJSON (Entity Feed)
      arising from a use of `toJSON'
    Matching instances:
      instance ToJSON e => ToJSON (Entity e)
        -- Defined in `persistent-1.2.0.1:Database.Persist.Class.PersistEntity'
      instance ToJSON (Entity Feed) -- Defined at Handler/Feed.hs:5:10
    In the second argument of `($)', namely
      `toJSON (Entity feedId feed)'
    In the second argument of `($)', namely
      `return $ toJSON (Entity feedId feed)'
    In a stmt of a 'do' block:
      provideRep $ return $ toJSON (Entity feedId feed)

似乎持久确实确实为ToJSON (Entity e) hereToJSON (Entity Feed)提供了一个实例,但是我可以以某种方式使用我的吗?

4

3 回答 3

5

如果为 提供实例Feed,则可以使用内置Entity e实例。添加json到您的实体行将自动创建该实例,请参阅: https ://github.com/yesodweb/persistent/wiki/Persistent-entity-syntax#json-instances

于 2013-05-08T20:33:12.453 回答
2

覆盖默认instances (这是 Yesod 的ToJSON e => ToJSON (Entity e)实例)的常用技巧是使用newtype.

newtype EntityFeed = EF (Entity Feed)
instance ToJSON EntityFeed where ...

虽然这可能有点不方便。

于 2013-05-08T05:37:24.363 回答
0

正如 tel 所说,您可以使用newtype定义不同的类型并规避限制。但是,如果使用新类型太不方便,您也可以使用语言扩展OverlappingInstances

这个扩展允许你有重叠的实例,只要总是有一个比另一个更具体(如果匹配,将被选择)。

(见http://hackage.haskell.org/trac/haskell-prime/wiki/OverlappingInstances

于 2013-05-08T09:05:38.190 回答