Skip to content

Instantly share code, notes, and snippets.

@mkrull
Created October 26, 2013 21:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkrull/7174912 to your computer and use it in GitHub Desktop.
Save mkrull/7174912 to your computer and use it in GitHub Desktop.
Key not present error in "the pragmatic haskeller" example from https://www.fpcomplete.com/user/adinapoli/the-pragmatic-haskeller/episode-1-json
key "name" not present in {
"name": "Ciambellone Cake",
"ingredients": [
{
"name": "Flour",
"quantity": 250,
"measure": "gr"
},
{
"name": "Sugar",
"quantity": 250,
"measure": "gr"
},
{
"name": "Sunflower Oil",
"quantity": 130,
"measure": "ml"
},
{
"name": "Water",
"quantity": 130,
"measure": "ml"
},
{
"name": "Egg",
"quantity": 3
},
{
"name": "Yeast",
"quantity": 1
}
],
"steps": [
{
"step": "Mix everything",
"order": 1
},
{
"step": "Cook in oven at 200 degrees",
"order": 2,
"duration": {
"duration": 30,
"measure": "minutes"
}
}
]
}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Aeson
import Control.Applicative
import Control.Monad
import Data.Monoid
import qualified Data.ByteString.Lazy.Char8 as C8
import qualified Data.ByteString.Lazy as BL
-- Types
data Recipe = Recipe {
recipeName :: String,
ingredients :: [Ingredient],
steps :: [Step]
} deriving Show
type Measure = String
data Ingredient = Ingredient {
ingredientName :: String,
qantity :: Int,
measure :: Maybe Measure
} deriving Show
data Step = Step {
stepName :: String,
order :: Int,
stepDuration :: Maybe Duration
} deriving (Eq, Show)
instance Ord Step where
compare s1 s2 = compare (order s1) (order s2)
data Duration = Duration {
duration :: Int,
durationMeasure :: Measure
} deriving (Eq, Show)
-- Parser
instance FromJSON Recipe where
parseJSON (Object r) = Recipe <$>
r .: "name" <*>
r .: "ingredients" <*>
r .: "steps"
parseJSON _ = mzero
instance ToJSON Recipe where
toJSON (Recipe n i s) = object ["name" .= n, "ingredients" .= i, "steps" .= s]
instance FromJSON Ingredient where
parseJSON (Object i) = Ingredient <$>
i .: "name" <*>
i .: "quantity" <*>
i .:? "measure"
parseJSON _ = mzero
instance ToJSON Ingredient where
toJSON (Ingredient n q m) = object ["name" .= n, "quantity" .= q, "measure" .= m]
instance FromJSON Step where
parseJSON (Object s) = Step <$>
s .: "name" <*>
s .: "order" <*>
s .:? "duration"
parseJSON _ = mzero
instance ToJSON Step where
toJSON (Step n o d) = object ["name" .= n, "order" .= o, "duration" .= d]
instance FromJSON Duration where
parseJSON (Object d) = Duration <$>
d .: "duration" <*>
d .: "measure"
parseJSON _ = mzero
instance ToJSON Duration where
toJSON (Duration d m) = object ["duration" .= d, "measure" .= m]
main :: IO ()
main = do
content <- BL.readFile "recipe.json"
case (eitherDecode' content :: Either String Recipe) of
Right r -> print r
Left e -> C8.putStrLn $ C8.pack e <> " in " <> content
{
"name": "Ciambellone Cake",
"ingredients": [
{
"name": "Flour",
"quantity": 250,
"measure": "gr"
},
{
"name": "Sugar",
"quantity": 250,
"measure": "gr"
},
{
"name": "Sunflower Oil",
"quantity": 130,
"measure": "ml"
},
{
"name": "Water",
"quantity": 130,
"measure": "ml"
},
{
"name": "Egg",
"quantity": 3
},
{
"name": "Yeast",
"quantity": 1
}
],
"steps": [
{
"step": "Mix everything",
"order": 1
},
{
"step": "Cook in oven at 200 degrees",
"order": 2,
"duration": {
"duration": 30,
"measure": "minutes"
}
}
]
}
@mkrull
Copy link
Author

mkrull commented Oct 26, 2013

changing "name" to "step" in Step instances fixes the problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment