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 が でありText、それからtoJSONa を作ることができ、 から a を作ることValueparseJSON知っParserていValueます。それで大丈夫ですよね?まあ、私はまだまったく有益ではない上記のエラーを受け取ります。何か案は?

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でありText、私たちは持っています

instance ToJSON Text where
    toJSON = String

Projectしたがって、上記の forループのインスタンスは、展開されるため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 に答える