basvandijk avatar basvandijk committed a3e0476

Encode the constructors of Either so that "fromJSON . toJSON == id" holds

Comments (0)

Files changed (1)

Data/Aeson/Types.hs

 {-# LANGUAGE DeriveDataTypeable, FlexibleInstances, GeneralizedNewtypeDeriving,
-    IncoherentInstances, OverlappingInstances, OverloadedStrings, Rank2Types #-}
+    IncoherentInstances, OverlappingInstances, OverloadedStrings, Rank2Types,
+    ViewPatterns #-}
 
 -- |
 -- Module:      Data.Aeson.Types
     {-# INLINE parseJSON #-}
 
 instance (ToJSON a, ToJSON b) => ToJSON (Either a b) where
-    toJSON (Left a)  = toJSON a
-    toJSON (Right b) = toJSON b
+    toJSON (Left a)  = object [left  .= a]
+    toJSON (Right b) = object [right .= b]
     {-# INLINE toJSON #-}
     
 instance (FromJSON a, FromJSON b) => FromJSON (Either a b) where
-    parseJSON a = Left <$> parseJSON a <|> Right <$> parseJSON a
+    parseJSON (Object (M.toList -> [(key, value)]))
+        | key == left  = Left  <$> parseJSON value
+        | key == right = Right <$> parseJSON value
+    parseJSON _ = mzero
     {-# INLINE parseJSON #-}
 
+left, right :: Text
+left  = "Left"
+right = "Right"
+
 instance ToJSON Bool where
     toJSON = Bool
     {-# INLINE toJSON #-}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.