[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