我试图通过解决一些在线练习问题来习惯一些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")])
从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一个很好的阅读。
Object
是Value
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字符串)。
以下是一些从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