0

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?

Alan Coromano
  • 24,958
  • 53
  • 135
  • 205
  • please add the error message to your question - because in this case the error message would have told you exactly wher ethe problem was - the missing `Maybe` – Random Dev Apr 25 '16 at 04:21

1 Answers1

3

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\" }]"

example

λ> decode example :: Maybe [MyData]
Just [MyData {a = 1, b = "Hello"},MyData {a = 2, b = "World"}]

your problem

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 type Maybe 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
Random Dev
  • 51,810
  • 9
  • 92
  • 119