
Dear Cafe, I need help parsing YAML files with varying structure. The minimal example is: a yaml file that has one key, which can hold either one key-value pair or two key value pairs. I have data types for the one key, and the two possible sub-keys:
data Var = Var { v' :: Either MyList Item } deriving Show
data MyList = MyList { a' :: Int, b' :: Int } deriving Show
data Item = Item { content' :: String } deriving Show
To read MyList and Item from the file I wrote FromJSON instances
instance FromJSON MyList where parseJSON (Object m) = MyList <$> m .: (pack "a") <*> m .: (pack "b") parseJSON x = fail ("not an object: " ++ show x)
instance FromJSON Item where parseJSON (Object m) = Item <$> m .: (pack "c") parseJSON x = fail ("not an object: " ++ show x)
I also have read functions for MyList and Item:
readItem :: IO Item readItem = either (error.show) id <$> decodeFileEither "test.yaml"
readMyList :: IO MyList readMyList = either (error.show) id <$> decodeFileEither "test.yaml"
The file test.yaml looks like
v: a: 4 b: 5
or, alternatively
v: c: "test"
The question is how I can decode test.yaml to get Var. Trying to code readVar like readItem (having FromJSON Var like FromJSON Item) failed. For convenience I attached the relevant source files. Regards, Johannes.