Reputation: 26008
I have a data class:
data MyData = MyData { a :: Int, b :: String }
instance ToJSON MyData where
....
instance FromJSON MyData where
....
I can parse a single object from json:
get :: IO (Maybe MyData)
get = do
res <- getSingleItemHttp
return $ decode $ responseBody res
How can I get a list of MyData?
get2 :: IO [MyData]
get2 = do
res <- getManyItemsHttp
--????
return $ decode $ responseBody res -- doesn't compile
How would I go about parsing responseBody to List
?
Upvotes: 0
Views: 1230
Reputation: 52280
It should work as it is once you pass in an array (and decode as a list) so you probably just have to change your signature to get2 :: IO (Maybe [MyData])
:
{-# LANGUAGE DeriveGeneric, OverloadedStrings #-}
module Json where
import GHC.Generics
import Data.Aeson
import Data.Text
import Data.ByteString.Lazy
data MyData = MyData { a :: Int, b :: String }
deriving (Generic, Show)
instance FromJSON MyData
example :: ByteString
example = "[{ \"a\": 1, \"b\": \"Hello\" }, { \"a\": 2, \"b\": \"World\" }]"
λ> decode example :: Maybe [MyData]
Just [MyData {a = 1, b = "Hello"},MyData {a = 2, b = "World"}]
would be something like this: if you try
get :: [MyData]
get = decode example
the compiler will complain with
Couldn't match expected type
[MyData]
with actual typeMaybe a0
…
which should give you a big hint.
You can still get your signature with Data.Maybe.maybeToList
:
get :: [MyData]
get = Prelude.concat . maybeToList $ decode example
Upvotes: 3