2013-05-08 122 views
3

我试图从Yesod 1.2中使用新的selectRep函数,但是我无法使json响应正常工作。为持久实体创建ToJSON实例

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)here一个实例,但我可以用我的ToJSON (Entity Feed)不知何故?

回答

2

重写默认instance s(这是Yesod的ToJSON e => ToJSON (Entity e)实例)的常用技巧是使用newtype

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

虽然这可能有点不方便。

0

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

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

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