Haskell, Aeson - Is there a better way of getting the info I need from USDA database?
up vote
2
down vote
favorite
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.
json haskell aeson
add a comment |
up vote
2
down vote
favorite
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.
json haskell aeson
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
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.
json haskell aeson
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.
json haskell aeson
json haskell aeson
edited Nov 11 at 19:54
Mark Seemann
181k33323555
181k33323555
asked Nov 11 at 18:38
atis
504
504
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
Define the types you'd like to deserialise into, for example:
-# LANGUAGE DeriveGeneric #-
module Q53251928 where
import Data.Aeson
import GHC.Generics
data Item = Item ndbno :: String deriving (Eq, Show, Generic)
instance FromJSON Item
data FoodStuff = FoodStuff item :: [Item] deriving (Eq, Show, Generic)
instance FromJSON FoodStuff
data RootJSON = RootJSON list :: FoodStuff deriving (Eq, Show, Generic)
instance FromJSON RootJSON
These types are the minimal types you'll need to access all the ndbno
values. You can add other labels to the types to capture other data, e.g. group
, start
, end
, etc.
I downloaded the file in the link and attempted to decode it from GHCi, which worked fine:
*Q53251928 Q53251928> decodeFileStrict "download.json" :: IO (Maybe RootJSON)
Just (RootJSON list = FoodStuff item = [Item ndbno = "45044170",
Item ndbno = "45044169",Item ndbno = "45287938",Item ndbno = "45314045",
Item ndbno = "45036851",Item ndbno = "45036824",Item ndbno = "45198766",
Item ndbno = "45270526",Item ndbno = "45270516",Item ndbno = "45374956",
Item ndbno = "45215370",Item ndbno = "45225694",Item ndbno = "45225696",
Item ndbno = "45217133",Item ndbno = "45053881",Item ndbno = "45270521",
Item ndbno = "45226407",Item ndbno = "45218344",Item ndbno = "45225703",
Item ndbno = "45335760",Item ndbno = "45221588",Item ndbno = "45193027",
Item ndbno = "45194338",Item ndbno = "45194331",Item ndbno = "45256801"])
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251928%2fhaskell-aeson-is-there-a-better-way-of-getting-the-info-i-need-from-usda-data%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
Define the types you'd like to deserialise into, for example:
-# LANGUAGE DeriveGeneric #-
module Q53251928 where
import Data.Aeson
import GHC.Generics
data Item = Item ndbno :: String deriving (Eq, Show, Generic)
instance FromJSON Item
data FoodStuff = FoodStuff item :: [Item] deriving (Eq, Show, Generic)
instance FromJSON FoodStuff
data RootJSON = RootJSON list :: FoodStuff deriving (Eq, Show, Generic)
instance FromJSON RootJSON
These types are the minimal types you'll need to access all the ndbno
values. You can add other labels to the types to capture other data, e.g. group
, start
, end
, etc.
I downloaded the file in the link and attempted to decode it from GHCi, which worked fine:
*Q53251928 Q53251928> decodeFileStrict "download.json" :: IO (Maybe RootJSON)
Just (RootJSON list = FoodStuff item = [Item ndbno = "45044170",
Item ndbno = "45044169",Item ndbno = "45287938",Item ndbno = "45314045",
Item ndbno = "45036851",Item ndbno = "45036824",Item ndbno = "45198766",
Item ndbno = "45270526",Item ndbno = "45270516",Item ndbno = "45374956",
Item ndbno = "45215370",Item ndbno = "45225694",Item ndbno = "45225696",
Item ndbno = "45217133",Item ndbno = "45053881",Item ndbno = "45270521",
Item ndbno = "45226407",Item ndbno = "45218344",Item ndbno = "45225703",
Item ndbno = "45335760",Item ndbno = "45221588",Item ndbno = "45193027",
Item ndbno = "45194338",Item ndbno = "45194331",Item ndbno = "45256801"])
add a comment |
up vote
3
down vote
accepted
Define the types you'd like to deserialise into, for example:
-# LANGUAGE DeriveGeneric #-
module Q53251928 where
import Data.Aeson
import GHC.Generics
data Item = Item ndbno :: String deriving (Eq, Show, Generic)
instance FromJSON Item
data FoodStuff = FoodStuff item :: [Item] deriving (Eq, Show, Generic)
instance FromJSON FoodStuff
data RootJSON = RootJSON list :: FoodStuff deriving (Eq, Show, Generic)
instance FromJSON RootJSON
These types are the minimal types you'll need to access all the ndbno
values. You can add other labels to the types to capture other data, e.g. group
, start
, end
, etc.
I downloaded the file in the link and attempted to decode it from GHCi, which worked fine:
*Q53251928 Q53251928> decodeFileStrict "download.json" :: IO (Maybe RootJSON)
Just (RootJSON list = FoodStuff item = [Item ndbno = "45044170",
Item ndbno = "45044169",Item ndbno = "45287938",Item ndbno = "45314045",
Item ndbno = "45036851",Item ndbno = "45036824",Item ndbno = "45198766",
Item ndbno = "45270526",Item ndbno = "45270516",Item ndbno = "45374956",
Item ndbno = "45215370",Item ndbno = "45225694",Item ndbno = "45225696",
Item ndbno = "45217133",Item ndbno = "45053881",Item ndbno = "45270521",
Item ndbno = "45226407",Item ndbno = "45218344",Item ndbno = "45225703",
Item ndbno = "45335760",Item ndbno = "45221588",Item ndbno = "45193027",
Item ndbno = "45194338",Item ndbno = "45194331",Item ndbno = "45256801"])
add a comment |
up vote
3
down vote
accepted
up vote
3
down vote
accepted
Define the types you'd like to deserialise into, for example:
-# LANGUAGE DeriveGeneric #-
module Q53251928 where
import Data.Aeson
import GHC.Generics
data Item = Item ndbno :: String deriving (Eq, Show, Generic)
instance FromJSON Item
data FoodStuff = FoodStuff item :: [Item] deriving (Eq, Show, Generic)
instance FromJSON FoodStuff
data RootJSON = RootJSON list :: FoodStuff deriving (Eq, Show, Generic)
instance FromJSON RootJSON
These types are the minimal types you'll need to access all the ndbno
values. You can add other labels to the types to capture other data, e.g. group
, start
, end
, etc.
I downloaded the file in the link and attempted to decode it from GHCi, which worked fine:
*Q53251928 Q53251928> decodeFileStrict "download.json" :: IO (Maybe RootJSON)
Just (RootJSON list = FoodStuff item = [Item ndbno = "45044170",
Item ndbno = "45044169",Item ndbno = "45287938",Item ndbno = "45314045",
Item ndbno = "45036851",Item ndbno = "45036824",Item ndbno = "45198766",
Item ndbno = "45270526",Item ndbno = "45270516",Item ndbno = "45374956",
Item ndbno = "45215370",Item ndbno = "45225694",Item ndbno = "45225696",
Item ndbno = "45217133",Item ndbno = "45053881",Item ndbno = "45270521",
Item ndbno = "45226407",Item ndbno = "45218344",Item ndbno = "45225703",
Item ndbno = "45335760",Item ndbno = "45221588",Item ndbno = "45193027",
Item ndbno = "45194338",Item ndbno = "45194331",Item ndbno = "45256801"])
Define the types you'd like to deserialise into, for example:
-# LANGUAGE DeriveGeneric #-
module Q53251928 where
import Data.Aeson
import GHC.Generics
data Item = Item ndbno :: String deriving (Eq, Show, Generic)
instance FromJSON Item
data FoodStuff = FoodStuff item :: [Item] deriving (Eq, Show, Generic)
instance FromJSON FoodStuff
data RootJSON = RootJSON list :: FoodStuff deriving (Eq, Show, Generic)
instance FromJSON RootJSON
These types are the minimal types you'll need to access all the ndbno
values. You can add other labels to the types to capture other data, e.g. group
, start
, end
, etc.
I downloaded the file in the link and attempted to decode it from GHCi, which worked fine:
*Q53251928 Q53251928> decodeFileStrict "download.json" :: IO (Maybe RootJSON)
Just (RootJSON list = FoodStuff item = [Item ndbno = "45044170",
Item ndbno = "45044169",Item ndbno = "45287938",Item ndbno = "45314045",
Item ndbno = "45036851",Item ndbno = "45036824",Item ndbno = "45198766",
Item ndbno = "45270526",Item ndbno = "45270516",Item ndbno = "45374956",
Item ndbno = "45215370",Item ndbno = "45225694",Item ndbno = "45225696",
Item ndbno = "45217133",Item ndbno = "45053881",Item ndbno = "45270521",
Item ndbno = "45226407",Item ndbno = "45218344",Item ndbno = "45225703",
Item ndbno = "45335760",Item ndbno = "45221588",Item ndbno = "45193027",
Item ndbno = "45194338",Item ndbno = "45194331",Item ndbno = "45256801"])
edited Nov 11 at 20:11
answered Nov 11 at 19:52
Mark Seemann
181k33323555
181k33323555
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251928%2fhaskell-aeson-is-there-a-better-way-of-getting-the-info-i-need-from-usda-data%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown