I have the following function:
parseUserBasic :: ByteString -> Either String [Either String UserBasic]
parseUserBasic x = do
xx <- parseItems x
pure $ fmap (eitherDecode . encode) (items xx)
However it's not very efficient because of pure $ fmap (eitherDecode . encode) (items xx)
- we are JSON encoding a Object
into a ByteString
, which we then decode into a UserBasic
. Is there a way to do this directly? I assume this function would have the type FromJSON a => Value -> Maybe a
.
The complete code:
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module UserBasic where
import GHC.Generics
import Data.Aeson
import Data.String.Conversions
import Data.ByteString.Lazy
data UserBasic = UserBasic
{ email :: String
, name :: String
, address_1 :: Maybe String
, address_2 :: Maybe String
, address_3 :: Maybe String
, address_4 :: Maybe String
} deriving (Generic, Show)
data Items = Items
{ items :: [Object]
} deriving (Generic, Show)
instance FromJSON Items where
instance ToJSON Items where
toEncoding = genericToEncoding defaultOptions
instance FromJSON UserBasic where
parseJSON = withObject "Person" $ \v -> UserBasic
<$> v .: "email"
<*> ((++) . (++ " ") <$> v .: "first_name" <*> v .: "last_name")
<*> v .: "first_name"
<*> v .: "first_name"
<*> v .: "first_name"
<*> v .: "first_name"
parseItems :: ByteString -> Either String Items
parseItems = eitherDecode
parseUserBasic :: ByteString -> Either String [Either String UserBasic]
parseUserBasic x = do
xx <- parseItems x
pure $ fmap (eitherDecode . encode) (items xx)