[Haskell-cafe] Parsing YAML with varying structure

Johannes Strecha j.strecha at gmail.com
Mon May 4 17:46:31 UTC 2015


Thanks for the hint. I wasn't aware of <|>. However, I couldn't get it to
work yet (due to missing background knowledge -- have to read up).

JS.

On Sun, May 3, 2015 at 9:26 AM, Michael Snoyman <michael at snoyman.com> wrote:

> I think the answer to your question revolves around the Alternative
> instance for Parser. Does the following code help?
>
> Var <$> ((Left <$> parseJSON) <|> (Right <$> parseJSON))
>
> 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."
>
> On Sat, May 2, 2015 at 3:56 PM Johannes Strecha <j.strecha at gmail.com>
> wrote:
>
>> 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.
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150504/da9c0c8c/attachment.html>


More information about the Haskell-Cafe mailing list