4

I would like to convert my json to below format. And to convert from below format to my record. Please check the code that I have written below.

{
    "uid" : "bob",
    "emailid" : "[email protected]",
    "email_verified" : "Y" // "Y" for EmailVerified and "N" for EmailNotVerified
}

I have below code where I am trying to convert user type to and from json using Aeson library in Haskell

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}

import Data.Monoid ((<>))
import GHC.Generics
import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson.Types

data User = User {
    userId :: String,
    userEmail :: String,
    userEmailVerified :: EmailState
  } deriving (Show, Generic)

data EmailState = EmailVerified | EmailNotVerified deriving (Generic, Show)

instance ToJSON User where
    toJSON u = object [
       "uid" .= userId u,
       "emailid" .= userEmail u,
       "email_verified" .= userEmailVerified u
       ]

instance FromJSON User where
    parseJSON = withObject "User" $ \v -> User
        <$> v .: "uid"
        <*> v .: "emailid"
        <*> v .: "email_verified"

instance ToJSON EmailState
instance FromJSON EmailState

However, My format that I am currently able to generate is like below

{
    "uid" : "bob",
    "emailid" : "[email protected]",
    "email_verified" : "EmailVerified"
}
1
  • You should also implement To/FromJSON instances for EmailState Commented Nov 27, 2017 at 10:40

2 Answers 2

5

You need to implement the ToJSON of EmailState yourself (so remove the instance ToJSON EmailState, and write it like):

instance ToJSON EmailState where
    toJSON EmailVerified = String "Y"
    toJSON EmailNotVerified = String "N"

You also will need to alter yhe parser:

instance FromJSON EmailState where
    parseJSON (String "Y") = return EmailVerified
    parseJSON (String "N") = return EmailNotVerified
    parseJSON _ = fail "Invalid JSON value to parse"
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Willem . Your solution does work . If possible can you also update your answer or point to a good resource so that a new comer to haskell like me can understand hackage documentation. Like in above case I was trying instance ToJSON EmailState where toJSON _ = "Y" which did not work obviously.
0

Awesome answer by Willem, Just to add to the syntax you can use -

instance FromJSON EmailState where
    parseJSON (String s) 
        | s == "Y" = return EmailVerified
        | s == "N" = return EmailNotVerified
        | otherwise = fail "Invalid JSON value to parse"

-- Note: otherwise = mzero -- is prefered

ref: https://mail.haskell.org/pipermail/beginners/2011-October/008791.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.