2013-05-08 83 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