Haskell, Aeson - Is there a better way of getting the info I need from USDA database?
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 |
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 |
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
182k33323555
182k33323555
asked Nov 11 at 18:38
atis
777
777
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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',
autoActivateHeartbeat: false,
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
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 |
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 |
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
182k33323555
182k33323555
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