1
我在計算如何定義FromJSON實例中定義兩種其他類型之間選擇的Enum類型時遇到了一些問題。我的直覺是,我對*>和(。:)運算符以及Aeson對象類型的工作方式沒有足夠的理解,但我無法解析編譯器錯誤然而。 (幸運的是,實例的toJSON是很簡單的。)使用Aeson(Haskell)解碼枚舉選擇
給定兩個孩子的數據類型,我可以這樣定義實例:
data ChoiceSelection =
ChoiceSelection
{ csValue :: Type1 -- Type2 here also works fine
} deriving (Show,Typeable)
data Type1 =
Type1
{ t1Value :: Int
} deriving (Show,Typeable)
data Type2 =
Type2
{ t2Value :: Bool
} deriving (Show,Typeable)
instance FromJSON ChoiceSelection where
parseJSON (Object x) = ChoiceSelection
<$> (x .: "csValue")
parseJSON _ = mzero
instance FromJSON Type1 where
parseJSON (Object x) = Type1
<$> (x .: "t1Value")
parseJSON _ = mzero
instance FromJSON Type2 where
parseJSON (Object x) = Type2
<$> (x .: "t2Value")
parseJSON _ = mzero
instance ToJSON ChoiceSelection where
toJSON (ChoiceSelection value) =
object [ "csValue" .= value
]
instance ToJSON Type1 where
toJSON (Type1 value) =
object [ "t1Value" .= value
]
instance ToJSON Type2 where
toJSON (Type2 value) =
object [ "t2Value" .= value
]
這工作得很好,但我一直無法定義一個實例FromJSON爲ExampleChoice
爲:
data ExampleChoice = Choice1 Type1
| Choice2 Type2
deriving (Show,Typeable)
data ChoiceSelection =
ChoiceSelection
{ csValue :: ExampleChoice
} deriving (Show,Typeable)
instance FromJSON ExampleChoice where
parseJSON (Object x) = -- ???
parseJSON _ = mzero
instance ToJSON ExampleChoice where
toJSON (Choice1 [email protected](Type1 _)) = toJSON t
toJSON (Choice2 [email protected](Type2 _)) = toJSON t
我想試試這個定義作爲MSUM,就像這樣:
instance FromJSON ExampleChoice where
parseJSON (Object x) =
msum [ -- Some attempt at parsing Type1
, -- Some attempt at parsing Type2
, mzero
]
parseJSON _ = mzero
但是,我還沒有能夠找出解析。
我還沒有嘗試過使用TemplateHaskell和deriveJSON來爲我定義這個,但即使這不會導致問題,我很好奇如何解決這個問題。
編輯:deriveJSON效果很好。儘管如此,我仍然很好奇如何通過手工來創建它。
我最終沒有得到像這樣工作,使用msum方法。我意識到我的問題是誤解了<$>運營商,現在我更瞭解fmap。我無法得到格式在這個評論工作,但在一行看起來像這樣:parseJSON(Object x)= msum [Choice1 <$> parseJSON x,Choice2 <$> parseJSON x] – stormont
此外,我注意到,自動派生使JSON包裝了ExampleChoice元素中的ChoiceN元素,但該解決方案很好地「隱藏」了JSON中顯示的ExampleChoice功能。 – stormont
這不會解析。 –