據我所知,沒有自定義泛型實例的方式,但你可以組織你的類型有點不同:
data Course = Course
{ courseId :: Maybe Text -- Don't use `id`, it's already a function
, name :: Text
} deriving (Show, Generic)
data Deletable a = Deletable
{ deleted :: Bool
, item :: a
} deriving (Show)
instance FromJSON Course
instance ToJSON Course
instance FromJSON a => FromJSON (Deletable a) where
parseJSON (Object v) = do
i <- parseJSON (Object v)
d <- v .:? "deleted" .!= False
return $ Deletable d i
parseJSON _ = mzero
現在你可以做
> let noDeleted = "{\"name\":\"Math\",\"courseId\":\"12345\"}" :: Text
> let withDeleted = "{\"name\":\"Math\",\"courseId\":\"12345\",\"deleted\":true}" :: Text
> decode noDeleted :: Maybe (Deletable Course)
Just (Deletable {deleted = False, item = Course {courseId = Just "12345", name = "Math"}})
> decode noDeleted :: Maybe Course
Just (Course {courseId = Just "12345", name = "Math"})
> decode withDeleted :: Maybe (Deletable Course)
Just (Deletable {deleted = True, item = Course {courseId = Just "12345", name = "Math"}})
> decode withDeleted :: Maybe Course
Just (Course {courseId = Just "12345", name = "Math"})
,現在你可以只需在需要時將課程標記爲可刪除,並且FromJSON
實例負責處理所有內容。