<div dir="ltr">I think the answer to your question revolves around the Alternative instance for Parser. Does the following code help?<br><br><div>Var <$> ((Left <$> parseJSON) <|> (Right <$> parseJSON))</div><div><br></div><div>What this is saying is "try to parse a MyList, and then wrap it with a Left. If that fails, try to parse an Item and wrap it with a Right. Whatever the result is from there, wrap it in a Var."</div></div><br><div class="gmail_quote">On Sat, May 2, 2015 at 3:56 PM Johannes Strecha <<a href="mailto:j.strecha@gmail.com">j.strecha@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div><div><div>Dear Cafe,<br><br></div>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:<br><br>>data Var = Var {<br>> v' :: Either MyList Item<br>> } deriving Show<br>><br>>data MyList = MyList {<br>> a' :: Int,<br>> b' :: Int<br>> } deriving Show<br>><br>>data Item = Item {<br>> content' :: String<br>> } deriving Show<br><br></div><div>To read MyList and Item from the file I wrote FromJSON instances<br></div><br>>instance FromJSON MyList where<br>> parseJSON (Object m) = MyList <$> m .: (pack "a") <*> m .: (pack "b")<br>> parseJSON x = fail ("not an object: " ++ show x)<br>><br>>instance FromJSON Item where<br>> parseJSON (Object m) = Item <$> m .: (pack "c")<br>> parseJSON x = fail ("not an object: " ++ show x)<br><br>I also have read functions for MyList and Item:<br><br>>readItem :: IO Item<br>>readItem = either (error.show) id <$> decodeFileEither "test.yaml"<br>><br>>readMyList :: IO MyList<br>>readMyList = either (error.show) id <$> decodeFileEither "test.yaml"<br><br></div>The file test.yaml looks like<br><br>>v:<br>> a: 4<br>> b: 5<br><br></div>or, alternatively<br><br></div>>v:<br></div>> c: "test"<br><br></div>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.<br><br></div>Regards,<br></div>Johannes.<br></div>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
</blockquote></div>