My goal is to write a program in Haskell that takes the name of the json file and interprets the rest of the arguments as a way to move that json file and prints the value to which the transition is made. The problem is that JSON can contain several types of values, I don’t know how to make a system like Haskell understand what I want. Here is the Haskell code with a “navigation” function that I cannot implement correctly:
import qualified Data.Aeson as A import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Lazy.Char8 as BSL import Data.List import Data.Maybe import System.Environment parse :: String -> A.Value parse = fromJust . A.decode . BSL.pack isInteger xs = case reads xs :: [(Integer, String)] of [(_, "")] -> True _ -> False navigate :: A.Value -> String -> String navigate value [] = value navigate value [x:xs] | isInteger x = ??? -- value is an array, get the xth element of it. | otherwise = ??? -- value is an map, x is a key in it. main :: IO () main = do [filename:path] <- getArgs contents <- readFile filename let d = parse contents putStrLn (show (navigate d path))
For reference, here is how the program was written in Python:
from json import load from sys import argv def navigate(obj, path): if not path: return obj head, tail = path[0], path[1:] return navigate(obj[int(head) if head.isdigit() else head], tail) if __name__ == '__main__': fname, path = argv[1], argv[2:] obj = load(open(fname)) print navigate(obj, path)
The program will start as follows:
$ cat data.json {"foo" : [[1, 2, 3, {"bar" : "barf"}]]} $ python showjson.py data.json foo 0 3 bar barf
source share