Ответ 1
Вы можете повторно использовать FromJSON
экземпляр Map String v
. Что-то вроде следующего:
{-# LANGUAGE OverloadedStrings #-}
import Data.Functor
import Data.Monoid
import Data.Aeson
import Data.Map (Map)
import qualified Data.ByteString.Lazy as LBS
import System.Environment
newtype City = City (Map String String)
deriving Show
instance FromJSON City where
parseJSON val = City <$> parseJSON val
newtype Country = Country (Map String City)
deriving Show
instance FromJSON Country where
parseJSON val = Country <$> parseJSON val
newtype DB = DB (Map String Country)
deriving Show
instance FromJSON DB where
parseJSON val = DB <$> parseJSON val
main :: IO ()
main = do
file <- head <$> getArgs
str <- LBS.readFile file
print (decode str :: Maybe DB)
Выход:
[email protected]:/tmp/shum$ cat in.js
{
"A": {
"A1": {
"A11": "1111",
"A22": "2222"
}
},
"B": {
}
}
[email protected]:/tmp/shum$ runhaskell test.hs in.js
Just (DB (fromList [("A",Country (fromList [("A1",City (fromList [("A11","1111"),("A22","2222")]))])),("B",Country (fromList []))]))
[email protected]:/tmp/shum$
PS: Вы можете сделать это без newtype
s, я использовал их только для ясности.