2012-11-15 8 views
0

json 서버의 I/O 측면에서 작업 중이며 방금 얻을 수없는 방법이 있습니다. 먼저 오류 코드를 입력 한 다음 코드 및 데이터 유형을 입력하고 나중에 문제에 대한 설명을 제공합니다.JSON 구문 분석 지원

("X-Response-Body-Start","<!DOCTYPE html>\n<html><head><title>Invalid Arguments</title></head><body><h1>Invalid Arguments</h1><ul><li>when expecting a unit constructor (U1), encountered String instead</li></ul></body></html>")

단위 생성자를 기대?

여기 관련 코드가 있습니다. 우리는 내가 어디로 볼 수 있는지 보자 잘못된 from Datatypes.hs

data JobID = JobID Project Int deriving Generic 

data Project = BNAP deriving (Show,Generic) -- one day to be an ADT 

instance ToJSON Project where 
    toJSON = toJSON . show 

instance FromJSON Project 

instance FromJSON JobID 
instance ToJSON JobID 

테스트 코드

testReadR :: IO Value 
testReadR = do 
    req <- parseUrl readURI 
    manager <- newManager def 
    pBody <- runResourceT $ do 
       reqBody <- readObject 
       liftIO $ print reqBody 
       Response _ _ _ body <- http (buildReq req reqBody) manager 
       pBody <- body $$+- sinkParser json 
       return pBody -- (return wraps it up) 
    closeManager manager 
    return pBody 

buildReq :: forall a (m :: * -> *) (t :: * -> *). 
      ToJSON a => 
      Request t -> a -> Request m 
buildReq req reqBody = 
    let reqBodyBS = Data.Aeson.encode reqBody 
     rHeaders = [(hContentType,pack "application/json")] 
    in req {method = fromString "POST" 
      , requestBody = RequestBodyLBS reqBodyBS 
      ,requestHeaders=rHeaders 
      } 
readObject :: ResourceT IO Value 
readObject = do -- I took a bunch out because I thought simplifiying would help me 
       -- solve this 
    return $ Data.Aeson.toJSON $ JobID BNAP 306 

핸들러

postReadR :: Handler RepJson 
postReadR = do 
    conf <- parseJsonBody_ :: Handler JobID   
    liftIO $ print conf 
    testJ <- jsonToRepJson $ toJSON $ JobID BNAP 305 
    jValue <- jsonToRepJson conf -- to be replaced with 
           -- Either ErrorReport Response 
           -- (or something like that) 
    return jValue 

나는 conf <- parseJsonBody_ :: Handler Value

에 줄을 변경하는 경우 print conf 수확량 Array (fromList [String "BNAP",Number 306])

그래서 "BNAP"문자열에 문제가있는 것 같습니다. 이유는 모르겠습니다. 내가 이것을 밖으로 내뱉을 수있는 방법에 대한 아이디어가 있습니까? 내가보기 싫은 확실한 대답이 있습니까?

업데이트 : 새로운 오류가 있습니다. 나는 FromJSON 인스턴스를 borked했는지 확신합니다.

test: ResponseTimeout 

instance FromJSON Project where 
    parseJSON (String p) = parseJSON $ toJSON p 
    parseJSON _ = mzero 

Project은 단일 유형입니다. 내가 연구 한 예제 중 어느 것도이를 해결하지 못했다. 하지만 p는 Text이고 toJSONValue이되고, parseJSONValue에서 Parser이됩니다. 그럼 괜찮은거야? 글쎄, 나는 아직도 유익하지 않은 위의 오류를 얻는다. 어떤 아이디어?

+0

내가 현재의 문제 해결을 믿는 것을 내 대답을 업데이트했습니다. –

답변

2
instance ToJSON Project where 
    toJSON = toJSON . show 

instance FromJSON Project 

인스턴스가 함께 작동하지 않습니다. 일반 FromJSON 인스턴스는 일반 단위 생성자 U1을 필요로하지만 ToJSON 인스턴스는 String "BNAP"을 생성합니다.

손으로 작성한 ToJSON 인스턴스가있는 경우 손으로 작성한 FromJSON 인스턴스가 필요합니다.


instance FromJSON Project where 
    parseJSON (String p) = parseJSON $ toJSON p 
    parseJSON _ = mzero 

p

Text이며, 우리는

instance ToJSON Text where 
    toJSON = String 

이 너무 Project 루프에 대해 위의 예, 그것은 parseJSON (String p) = parseJSON (String p)을 확장하기 때문이다.지금의 약자로 유형으로

, 당신이 사용할 수 OverloadedStrings이있는 경우없는 경우
instance FromJSON Project where 
    parseJSON (String "BNAP") = return BNAP 
    parseJSON _    = mzero 

이 작동해야

instance FromJSON Project where 
    parseJSON (String p) 
     | p == pack "BNAP" = return BNAP 
    parseJSON _   = mzero 
+0

고마워, 고칠 수있어. –