如何在Haskell,Aeson中获取HashMap(Object)的价值?

问题描述 投票:0回答:3

我试图通过解决一些在线练习问题来习惯一些haskell库。

我有一些输出这个的代码

Object (fromList [("ABC", String "123")])

它也可能是

Object (fromList [("123", String "ABC")])
Object (fromList [(String "123", String "ABC")])
Object (fromList [("123", "ABC")])

我需要提取的是"123"

使用具有.:类型的(.:) :: FromJSON a => Object -> Text -> Parser a来提取给定键的值会引发此错误

• Couldn't match type ‘Value’ with ‘HashMap Text Value’                                                         
  Expected type: Object
    Actual type: Value

我最好的猜测是,我将不得不编写一个解析器,但我不知道如何去做或者寻找什么。

产生错误的代码:

x <- (eitherDecode <$> simpleHttp url) :: IO (Either String DataSet)
  case x of
    Left er   -> print er
    Right an -> do
      let l = S.toList (data1 an)
      print $ l .: "ABC"

其中DataSet的定义如下

newtype DataSet = DataSet {
                   data1  :: Object
                   } deriving (Show, Generic)

如果我要更换

print $ (Data.List.head l) .: "ABC"

只是

print $ (Data.List.head l)

我明白了

Object (fromList [("ABC", String "123")])
parsing haskell aeson
3个回答
0
投票

Value类型中获取东西的一种快速而肮脏的方法是

Value编码为ByteString

encode有encode :: ToJSON a => a -> ByteString类型

所以在你的代码中

...
  case x of
    Left er   -> print er
    Right an -> do
      let l = S.toList (data1 an)
          x = (encode . snd) l  -- you can replace snd with fst if you want "ABC" instead of "123"
          y = decode x :: Maybe (HashMap String String)
          case y of
              Nothing -> print "got nothing"
              Just a -> print $ Data.HashMap.Strict.toList a

这将输出如下列表:

[("123")]

现在,您可以使用简单的函数提取值。

希望有所帮助。

要了解更多关于如何更好地解析JSON文件,我建议给https://artyom.me/aeson一个很好的阅读。


2
投票

ObjectValue type的几个建设者之一

Haskell Constructor | JSON Syntax
Object              | {"key": "value"}
String              | "hello"
Number              | 123
Array               | [1, 2, 3]

请注意,在这种情况下,构造函数Object不是Object类型的构造函数。 [最后注意。]

错误来自于将Value传递给期待Object的某个函数。如果遇到任何其他情况,您将需要定义程序应该执行的操作。

或者因为你有data1 an :: Object,你可以在那里查找你想要的密钥。我不确定S.toList的类型是什么,但你似乎将你的Object转换为Value,然后将它传递给需要物体的.:

最后的注释:Object (fromList [("ABC", String "123")])是一个具有一个键值对的单个值。 fromList是一种从部件创建对象的方法(而不是通过解析JSON字符串)。


0
投票

以下是一些从Object数据类型中解开Value构造函数的方法。

你可以创建一个解包函数:

unwrapValue :: Value -> Object
unwrapValue (Object x) = x
unwrapValue _ = error "No Object available"

请注意,此函数将返回错误,因为有可能Value不会是Object

另外,不要被Object混淆,因为Value既是getNum :: Array -> Either String Scientific getNum someArray = flip parseEither someArray $ \arr -> do let Just (Object obj) = arr !? 1 -- Unsafe unwrap Object constructor from Value (also unwraps Just constructor from Maybe) (Number num) <- obj .: "myNumber" -- Unsafe unwrap Number constructor from Value return num 的构造者又是aeson中的一种类型!

您也可以解压缩内联,但它也不安全,这意味着它可能导致运行时错误。例如:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.