I have a complex nested json, which i'm trying to parse with Aeson and Attoparsec, into my custom types. Based on info from questions: Haskell, Aeson & JSON parsing into custom type, Aeson: How to convert Value into custom type? and some info from Internet.
When I'm using following code I'm getting "Nothing" Value from overlapped FromJSON instance, but code goes through each instance for sure, I've tested this by disabling some other insances. So the main question : how to test code in instances and see how data changes over execution in GHCi?
P.S: Tried to set breakpoints and "trace", but they are worked only in main & parseCfg functions.
{-# LANGUAGE OverloadedStrings, FlexibleInstances #-}
-- high level data
data Cfg = Cfg { nm :: CProperty,
author :: CProperty,
langs :: CValue,
grops :: CListArr,
projs :: CPropArr
} deriving (Show)
...
instance FromJSON CProperty where
parseJSON _ = mzero
parseJSON (Object o) = CProperty <$> toCProperty o
where
toCProperty :: (HM.HashMap T.Text Value) -> J.Parser (T.Text, T.Text)
toCProperty _ = error "unexpected property"
toCProperty o' = do
l <- return $ HM.toList o'
k <- return $ fst $ head l
v <- return $ snd $ head l
v' <- parseJSON v
return $ (k, v')
... lot's of different instances
-- |this instance is specific for different files
-- based on common functions to work with most of nested json code
instance FromJSON Cfg where
parseJSON _ = mzero
parseJSON (Object o) = do
nm <- (parseJSON :: Value -> J.Parser CProperty) =<< (o .: T.pack "Name")
autor <- (parseJSON :: Value -> J.Parser CValue) =<< (o .: T.pack "Author")
langs <- (parseJSON :: Value -> J.Parser CProperty) =<< (o .: T.pack "Languages")
groups <- (parseJSON :: Value -> J.Parser CListArr) =<< (o .: T.pack "Groups")
projs <- (parseJSON :: Value -> J.Parser CPropArr) =<< (o .: T.pack "Projects")
return $ Cfg nm author langs groups projs
------------------------------------------------------------------------------------
main :: IO ()
main = do:
s <- L.readFile "/home/config.json"
-- print $ show s
let cfg = parseCfg s
print $ show $ cfg
parseCfg :: L.ByteString -> Maybe Cfg
parseCfg s = decode s