Skip to content

Instantly share code, notes, and snippets.

@nkpart
Created August 26, 2015 03:34
Show Gist options
  • Save nkpart/7520574744151a9e3042 to your computer and use it in GitHub Desktop.
Save nkpart/7520574744151a9e3042 to your computer and use it in GitHub Desktop.
Consuming keys from a json object
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.Yaml.Extended (module Data.Yaml.Extended, lift) where
import Data.Yaml
import qualified Data.Text as T
import Control.Monad.State.Strict (StateT, runStateT, unless, lift, get, modify)
import qualified Data.HashMap.Strict as HM (null, delete, keys)
import Data.List (intercalate)
useKey :: FromJSON v => T.Text -> StateT Object Parser v
useKey k = do o <- get
v <- lift (o .: k)
modify (HM.delete k)
return v
failUnlessEmpty :: StateT Object Parser x -> Object -> Parser x
failUnlessEmpty sm o = do (x, o') <- runStateT sm o
unless (HM.null o') (failWithExtra (HM.keys o'))
return x
failWithExtra :: (Monad m, Show a) => [a] -> m ()
failWithExtra unused = fail ("Unhandled fields in JSON object: " ++ v unused)
where v = intercalate ", " . map show
ex1 :: Object -> Parser (String, Int)
ex1 = failUnlessEmpty $ do v <- useKey "name"
x <- useKey "age"
return (v, x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment