Json Aeson:解析枚举数据类型

Json Aeson:解析枚举数据类型,json,haskell,aeson,Json,Haskell,Aeson,如何声明以下数据类型的FromJSON实例: data Privacy = Everyone | AllFriends | FriendsOfFriends | Self 因此,枚举数据类型的字符串如下: "EVERYONE" -> Everyone "ALL_FRIENDS" -> AllFriends "FRIENDS_OF_FRIENDS" -> FriendsOfFriends "SELF" -&

如何声明以下数据类型的FromJSON实例:

data Privacy = Everyone | 
           AllFriends | 
           FriendsOfFriends | 
           Self
因此,枚举数据类型的字符串如下:

"EVERYONE" -> Everyone
"ALL_FRIENDS" -> AllFriends
"FRIENDS_OF_FRIENDS" -> FriendsOfFriends
"SELF" -> Self
_ -> Parsing error
暗示了一个可能的解决方案,但我无法编译该代码


谢谢

我找到的解决方案是使用
Control.Applicative
中的
pure

import Control.Applicative ((<$>), (<*>), pure)

data Privacy = Everyone | 
       AllFriends | 
       FriendsOfFriends | 
       Self

instance FromJSON Privacy where
  parseJSON (String s) =  pure $ mkPrivacy s
  parseJSON _ = fail "Failed to parse Privacy object"

instance ToJSON Privacy where
  toJSON Everyone = "EVERYONE"
  toJSON AllFriends = "ALL_FRIENDS"
  toJSON FriendsOfFriends = "FRIENDS_OF_FRIENDS"
  toJSON Self = "SELF"

mkPrivacy :: Text -> Privacy
mkPrivacy "EVERYONE" = Everyone
mkPrivacy "ALL_FRIENDS" = AllFriends
mkPrivacy "FRIENDS_OF_FRIENDS" = FriendsOfFriends
mkPrivacy "SELF" = Self
mkPrivacy _ = error "Invalid privacy token"
import Control.Applicative((),(),pure)
数据隐私=每个人|
所有朋友
朋友朋友|
自己
实例FromJSON隐私,其中
parseJSON(字符串s)=纯$mks
parseJSON=失败“未能分析隐私对象”
实例ToJSON隐私在哪里
toJSON everybody=“everybody”
toJSON AllFriends=“所有朋友”
toJSON FriendsOfFriends=“朋友中的朋友”
toJSON Self=“Self”
mkPrivacy::Text->Privacy
mk“所有人”=所有人
mkPrivacy“所有朋友”=所有朋友
mkPrivacy“朋友中的朋友”=朋友中的朋友
“自我”=自我
mkPrivacy=错误“无效的隐私令牌”

FromJSON定义应为:

instance FromJSON Privacy where
     parseJSON (Object v) = createPrivacy <$> (v .: "value")
来自JSON隐私的实例,其中
parseJSON(对象v)=createPrivacy(v.:“值”)
完整的工作示例:

{-# LANGUAGE OverloadedStrings #-}

import Data.Text
import Data.Aeson
import Control.Applicative
import Control.Monad

data Privacy = Everyone |
               AllFriends |
               FriendsOfFriends |
               Self
  deriving (Show)

instance FromJSON Privacy where
     parseJSON (Object v) = createPrivacy <$> (v .: "value")
     parseJSON _          = mzero

createPrivacy :: String -> Privacy
createPrivacy "EVERYONE" = Everyone
createPrivacy "ALL_FRIENDS" = AllFriends
createPrivacy "FRIENDS_OF_FRIENDS" = FriendsOfFriends
createPrivacy "SELF" = Self
createPrivacy _ = error "Invalid privacy setting!"

main = do
    let a = decode "{\"value\":\"ALL_FRIENDS\",\"foo\":12}" :: Maybe Privacy
    print a
{-#语言重载字符串}
导入数据.Text
导入数据.Aeson
导入控制
进口管制
数据隐私=每个人|
所有朋友|
朋友朋友|
自己
派生(显示)
实例FromJSON隐私,其中
parseJSON(对象v)=createPrivacy(v.:“值”)
parseJSON=mzero
createPrivacy::String->Privacy
createPrivacy“EVERYONE”=所有人
createPrivacy“所有朋友”=所有朋友
createPrivacy“朋友中的朋友”=朋友中的朋友
createPrivacy“SELF”=SELF
createPrivacy=错误“隐私设置无效!”
main=do
让a=解码“{\'value\”:“所有的朋友”,“foo\”:12}”::可能是隐私
打印

这种方法涉及较少的样板文件,但由于
T.unpack

data Privacy = Everyone | AllFriends | FriendsOfFriends | Self deriving (Read, Show)

instance FromJSON Privacy where
  parseJSON (String s) = fmap read (pure $ T.unpack s)
  parseJSON _ = mzero

谢谢你的回答。最后使用了我在回答中描述的模式,因为我有一个枚举数据类型作为JSON对象的属性。使用“value”要求我有一个额外的不必要的嵌套级别。然而,您的代码回答了我的问题。