I'm a Haskell beginner trying to learn JSON parsing by going through USDA database.
I want to get the value of "ndbno" key from this link
https://api.nal.usda.gov/ndb/search/?format=json&q=potato+salad&sort=n&max=25&offset=0&api_key=DEMO_KEY
The JSON file from that link looks like this:
{
"list": {
"q": "potato salad",
"sr": "1",
"ds": "any",
"start": 0,
"end": 25,
"total": 251,
"group": "",
"sort": "n",
"item": [
{
"offset": 0,
"group": "Branded Food Products Database",
"name": "AHOLD, DEVILED EGG POTATO SALAD, UPC: 688267141584",
"ndbno": "45044170",
"ds": "LI",
"manu": "Ahold USA, Inc."
},
{
"offset": 1,
"group": "Branded Food Products Database",
"name": "AHOLD, REDSKIN POTATO SALAD, UPC: 688267141591",
"ndbno": "45044169",
"ds": "LI",
"manu": "Ahold USA, Inc."
},
...
"nbdno" key is 4th in "item"
{-# LANGUAGE DeriveGeneric #-}
module Lib
( someFunc
) where
import Data.Aeson
import Data.HashMap.Strict as HS
import Data.List as L
import Data.Maybe
import Data.Text
import Data.Vector as V
import GHC.Generics
import Network.HTTP.Conduit
import Text.Pretty.Simple
data Food = Name (String, Text)
| Stuff (String, Int)
deriving (Eq, Read, Show, Generic)
someFunc :: IO ()
someFunc = putStrLn "Under Consruction!"
apiKey = "https://api.nal.usda.gov/ndb/search/?format=json&q=chana+dal&sort=n&max=25&offset=0&api_key=jJN9dsKFe507qjLVqbecijtrYB4AiojXVIt1EaEZ"
instance FromJSON Food
unString x = case x of
String x -> x
unObject x = case x of
Object x -> x
unArray x = case x of
Array x -> x
getParsed :: IO ()
getParsed = do
x <- simpleHttp apiKey
let y = (unObject . snd . L.head . HS.toList . fromJust) (decode x :: Maybe Object)
z = (unArray . snd . L.last . L.init) (HS.toList y)
a = V.map (unpack . unString . snd . L.head . L.drop 5 . HS.toList . unObject) z
b = V.map (\x -> read x :: Int) a
pPrint b
The way I implemented it is quite messy, but it gets the job done.
It's just that the code looks really bad and almost impossible to read. So I was wondering if there's a better way of doing that.