2014-02-06 49 views
1

我對Haskell來說相當新,所以我的意思是缺少一些簡單的東西。現在,我只是想從stdin中讀取一些JSON,並將AST作爲概念證明。Aeson:「當期望一個字符串時,遇到了一個對象」

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 

我有這樣的JSON片段(其中JSONLint說是確定):

{ 
    "foo": 123 
} 

當我的程序與輸入,我得到:

$ cat examples/object.json | runhaskell Main.hs 
Bad JSON: when expecting a String, encountered Object instead 

當我在一個測試文件是空陣列,它表示它「遇到陣列」。

所以我猜我錯過了某種轉換步驟在這裏,或者我正在從stdin讀取不正確。你怎麼看?

+1

我把你的代碼插入到SO的標記中。你可以在你的帖子上點擊「編輯」來查看如何操作的例子。 SO在每行代碼之前使用4個空格(很像降價)來表示代碼。您可以選擇在代碼之前添加一個'<! - language:lang - >'標籤來指定要使用的語法高亮顯示。它猜測你的代碼應該用任何主標籤來突出顯示,所以如果你發佈到haskell標籤,它會假設Haskell語法。 – bheklilr

+0

謝謝!我認爲它不是太複雜,但我必須運行,不想讓別人說「好吧,你的代碼不能編譯,所以出現問題」。 :-) – AndrewO

回答

6

問題是這樣的線:

putStrLn value 

由於putStrLn類型是String -> IO(),的value類型被推斷爲String,所以將使用FromJSON實例串,這將僅解碼字符串,因爲這是類型可以處理的。要解碼別的東西,你需要一個不同的類型value

嘗試

print (value :: JSON.Object) 

,如果你希望一個對象,或

print (value :: JSON.Value) 

如果任何JSON值是可以接受的。

請注意使用print而不是putStrLnprint接受任何類型的Show實例,因此與putStrLn不同,它不會強制其參數爲字符串。另請注意,沒有類型註釋的print value在此示例中將不起作用,因爲編譯器不會推導出哪些類型的value應具有哪些類型的信息,因此不會有足夠的信息來使用哪個ShowFromJSON實例。

+0

啊,好的 - 有道理。它看起來像我也可以做'putStrLn $ show value'(儘管我得到一個lint警告)。這更習慣嗎? – AndrewO

+1

[這就是'print'的定義](http://hackage.haskell.org/package/base/docs/src/System-IO.html#print),所以使用'print'更加地道。 – hammar

相關問題