Aeson:"当期待一个字符串时,遇到了一个对象"

And*_*ewO 1 json haskell aeson

我是Haskell的新手,所以我想错过一些简单的东西.现在,我只是尝试从stdin读取一些JSON并将AST作为概念证明.

module JSONStuff where

import qualified Data.Aeson as JSON
import qualified Data.ByteString.Lazy.Char8 as Char

main :: IO ()
main = do
    input <- Char.getContents
    case JSON.eitherDecode input of
        Left err -> putStrLn $ "Bad JSON: " ++ err
        Right value -> do
            putStrLn "Got:"
            putStrLn value
Run Code Online (Sandbox Code Playgroud)

我有这个JSON片段(JSONLint说没问题):

{
  "foo": 123
}
Run Code Online (Sandbox Code Playgroud)

当我使用该输入的程序时,我得到:

$ cat examples/object.json | runhaskell Main.hs
Bad JSON: when expecting a String, encountered Object instead
Run Code Online (Sandbox Code Playgroud)

当我测试一个和空数组的文件时,它说它"遇到了数组".

所以我猜我在这里缺少某种转换步骤,或者我正在从stdin中错误地读取.你怎么看?

ham*_*mar 7

问题是这一行:

putStrLn value
Run Code Online (Sandbox Code Playgroud)

由于putStrLnis String -> IO ()的类型value被推断为String,所以FromJSON将使用字符串的实例,这将只解码字符串,因为这是类型可以处理的.要解码别的东西,你需要一个不同的类型value.

尝试

print (value :: JSON.Object)
Run Code Online (Sandbox Code Playgroud)

如果你期望一个对象,或者

print (value :: JSON.Value)
Run Code Online (Sandbox Code Playgroud)

如果任何JSON值是可接受的.

注意使用print而不是putStrLn.print接受任何带有Show实例的类型,因此不像putStrLn它强制它的参数是一个字符串.另请注意,print value如果没有类型注释在此示例中不起作用,因为编译器没有足够的信息来推断value应该具有哪种类型,因此要使用哪些ShowFromJSON实例.