Преобразовать конструктор в записи в пользовательскую строку json в aeson haskell

Я хотел бы преобразовать свой json в формат ниже. И конвертировать из формата ниже в мою запись. Пожалуйста, проверьте код, который я написал ниже.

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

У меня есть код ниже, где я пытаюсь преобразовать пользовательский тип в json и из него, используя библиотеку Aeson в 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

Однако мой формат, который я сейчас могу создать, выглядит следующим образом:

{
    "uid" : "bob",
    "emailid" : "[email protected]",
    "email_verified" : "EmailVerified"
}

person navin    schedule 27.11.2017    source источник
comment
Вы также должны реализовать To/FromJSON экземпляры для EmailState   -  person 4e6    schedule 27.11.2017


Ответы (2)


Вам нужно реализовать ToJSON из EmailState самостоятельно (поэтому удалите instance ToJSON EmailState и напишите так):

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

Вам также нужно будет изменить синтаксический анализатор:

instance FromJSON EmailState where
    parseJSON (String "Y") = return EmailVerified
    parseJSON (String "N") = return EmailNotVerified
    parseJSON _ = fail "Invalid JSON value to parse"
person Willem Van Onsem    schedule 27.11.2017
comment
Спасибо Виллем. Ваше решение работает. Если возможно, вы также можете обновить свой ответ или указать на хороший ресурс, чтобы новый пользователь haskell, такой как я, мог понять документацию по взлому. Как и в приведенном выше случае, я пытался использовать экземпляр ToJSON EmailState, где toJSON _ = Y, что явно не сработало. - person navin; 27.11.2017

Потрясающий ответ Виллема. Просто добавьте к синтаксису, который вы можете использовать -

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

-- Примечание: в противном случае предпочтительнее = mzero --

ссылка: https://mail.haskell.org/pipermail/beginners/2011-October/008791.html

person Ishmum Khan    schedule 29.10.2018