0

我正在研究我的 json 服务器的 I/O 方面,并且有一种方法我无法正确处理。首先,我将给出错误,然后是涉及的代码和数据类型,以及之后对问题的一些评论。

("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实例。

test: ResponseTimeout

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

这里的挑战是它Project是一元类型。我研究的例子似乎都没有解决这个问题。但是我知道 p 是 a Text,并且toJSON可以从中Value得出a ,并且可以得出parseJSONa 。所以一切都好吗?好吧,我仍然收到上述错误,这根本没有信息。有任何想法吗?ParserValue

4

1 回答 1

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是 a Text,我们有

instance ToJSON Text where
    toJSON = String

所以上面的 forProject循环实例,因为它扩展了parseJSON (String p) = parseJSON (String p).

对于现在的类型,

instance FromJSON Project where
    parseJSON (String "BNAP") = return BNAP
    parseJSON _               = mzero

如果您启用了应该可以工作OverloadedStrings,如果没有,

instance FromJSON Project where
    parseJSON (String p)
        | p == pack "BNAP" = return BNAP
    parseJSON _            = mzero
于 2012-11-15T00:44:54.517 回答