[Haskell-cafe] Parsing YAML with varying structure

Michael Snoyman michael at snoyman.com
Sun May 3 07:26:21 UTC 2015


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/20150503/30210b15/attachment.html>


More information about the Haskell-Cafe mailing list