2016-11-22 3 views
3

내가 IO에서 JSON 구문 분석을 할 노력하고있어 : 하스켈 아이손 : 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을 얻으시겠습니까?

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

당신은 예를 들어,이 그렇다면 :

+2

을 할 수

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

이 있습니다. "이름"'에서 'IO'이지만, 단지'파서 '값입니다. 나는 Aeson에 익숙하지 않지만, 당신은 (Data.Aeson.Types.parse' 또는'parseMaybe'로) 순전히 파서를 실행해야한다고 생각합니다. –

답변

3

아이손은 Parser aa에에서 이동하는 기능의 무리가 있습니다

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

는 당신은 그래서 당신은 당신이 fromJust <$> 응답 '의 결과를 결합하려는 것 같습니다

{-# 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 -> 파서 문자열'및'response :: Value '이므로, 우리는 parseMaybe :: (a -> Parser b) -> a -> Maybe b'를'a ~ Value'와'b ~ String'으로 적용 할 수 있습니다. – Cactus

+1

물론'name'을 사용하는 경우 (예를 들어'print "hi"'에서 putStrLn $ unwords [ "Hi,", name]'로 마지막 라인을 변경하는 것과 같이) 'let name = ...'줄에 타입 주석이 필요 없다. – Cactus