2016-11-22 84 views
3

我試圖做的JSON解析在IO:哈斯克爾埃宋:如何獲取價值解析器的IO單子

{-# LANGUAGE OverloadedStrings #-} 
import Network.HTTP.Simple 
import Data.Aeson 
import Data.Maybe (fromJust) 

main :: IO() 
main = do 
    response <- getResponseBody <$> httpJSON "http://localhost:9200" :: IO Object 
    name <- fromJust <$> response .: "name" :: Parser String 
    print "hi" 

我得到的錯誤:

/home/nut/dev/haskell/elastic/app/Main.hs:39:11: error: 
    • Couldn't match type ‘Parser’ with ‘IO’ 
     Expected type: IO String 
     Actual type: Parser String 
    • In a stmt of a 'do' block: 

所以,我該怎麼辦從json結果中獲得name

+2

它看起來像你想的'fromJust <$>響應結果綁定: 「名字」 在' 'IO',但它只是一個'Parser'值。我對Aeson並不是很熟悉,但我認爲你需要使用'Data.Aeson.Types.parse'或'parseMaybe'運行解析器(純粹)。 –

回答

3

埃宋有一堆的功能,從Parser aa去:

parse  :: (a -> Parser b) -> a -> Result b 
parseEither :: (a -> Parser b) -> a -> Either String b 
parseMaybe :: (a -> Parser b) -> a -> Maybe b 

所以如果你有例如

(.: "name") :: Object -> Parser String 

,那麼你必須

parseMaybe (.: "name") :: Object -> Maybe String 

所以你可以做

{-# LANGUAGE OverloadedStrings #-} 
import Network.HTTP.Simple 
import Data.Aeson 
import Data.Maybe (fromJust) 
import Data.Aeson.Types -- new import for parseMaybe 

main :: IO() 
main = do 
    response <- getResponseBody <$> httpJSON "http://localhost:9200" 
    let name = fromJust $ parseMaybe (.: "name") response :: String 
    print "hi" 
+0

現在我有點困惑。不會是'(。:「name」):: Value - > Parser String'? 「Object」的類型是「Value」?對不起,對Aeson圖書館感到困惑...... – LudvigH

+0

是的,這是正確的。整個表達式'fromJust $ parseMaybe(。:「name」)response'就是我們註解的類型'String':'(。:「name」):: Value - > Parser String','response :: Value ',所以我們可以用'a〜Value'和'b〜String'來應用'parseMaybe ::(a - > Parser b) - > a - > Maybe b'。 – Cactus

+1

當然,如果我們只是使用'name'來完成任何事情(比如將最後一行從'print'hi''改成'putStrLn $ unwords [「Hi,」,name]'),它規定了它的類型,那麼我們不需要'let name = ...'行中的類型註釋。 – Cactus