2017-08-08 92 views
2

我有一個模塊Foo.hs其中包含不派生Generic一個定義:同時派生Generic和ToJSON?

-- Foo.hs 
data Blather = Blather ... -- Generic not derived here 

而在另一個模塊我想獲得ToJSON

-- Bar.hs 
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-} 

import GHC.Generics 
import Data.Aeson 

instance Generic Blather 
instance ToJSON Blather 

但它不會編譯。如果我在定義站點的Foo.hs中推導出Generic,則我可以稍後在另一個模塊中推導出ToJSON

我可以在Bar.hs中得出ToJSON Blather而無需修改原始Foo.hs

或者有沒有簡單的方法手寫instance ToJSON Blather

+0

它是否與['StandaloneDeriving'分機]工作(https://downloads.haskell.org/~ghc/7.8.4/docs/html/users_guide/deriving.html )? –

+0

爲什麼你不想在你定義類型的地方派生'Generic'?孤兒實例是邪惡的! – dfeuer

+0

是的,這將是正確的解決方案,但在此時我不想提交修改'Foo.hs'的PR。 – ErikR

回答

4

啓用StandaloneDeriving並使用deriving instance ...,因爲這並不要求派生與數據類型在同一模塊中。

實施例:

{-# LANGUAGE DeriveGeneric, StandaloneDeriving, DeriveAnyClass #-} 

import GHC.Generics 
import Data.Aeson 
import Foo 

deriving instance Generic Blather 
deriving instance ToJSON Blather 

main = undefined 
+0

啊 - 我按照[這裏]的配方(https://artyom.me/aeson#records-and-json-generics),只是使用'instance ...'而不是'派生實例'。 – ErikR

+1

@ErikR給出一個空的實例聲明適用於'ToJSON',但不適用於'Generic'。原因有點微妙:'Generic'是派生內置的類。 'ToJSON'是一個通用的「默認簽名」和實現給出的類。 – kosmikus