2016-07-29 10 views
0

ich folgendes Haskell habe meine WCF-Dienst zu nennen:Convert JSON zurück zu Daten in Haskell

{-# LANGUAGE OverloadedStrings #-} 
{-# LANGUAGE DeriveGeneriC#-} 

module Main where 

import Data.Aeson 
import Data.Dynamic 
import Data.Aeson.Lens 
import Data.ByteString.Lazy as BS 
import GHC.Generics 
import Network.Wreq 
import Control.Lens 

data Point = Point { x :: Int, y :: Int } deriving (Generic, Show) 
instance ToJSON Point 
instance FromJSON Point 

data Rectangle = Rectangle { width :: Int, height :: Int, point :: Point } deriving (Generic, Show) 
instance ToJSON Rectangle 
instance FromJSON Rectangle 

main = do   
    let p = Point 1 2 
    let r = Rectangle 10 20 p 
    let url = "http://localhost:8000/Rectangle" 
    let opts = defaults & header "Content-Type" .~ ["application/json"] 
    r <- postWith opts url (encode r)  
    let returnData = r ^? responseBody 
    case (decode returnData) of 
     Nothing  -> BS.putStrLn "Error decoding JSON" 
     Just json  -> BS.putStrLn $ show $ decode json 

Der Ausgang ist in diesem Fall:

Just "{\"height\":20,\"point\":{\"x\":1,\"y\":2},\"width\":10}" 

Ich habe bereits versucht es mit fromJSON:

print $ fromJSON returnData 

und bekam diesen Fehler:

Couldn't match expected type `Value' 
       with actual type `Maybe 
            bytestring-0.10.6.0:Data.ByteString.Lazy.Internal.ByteString' 
    In the first argument of `fromJSON', namely `returnData' 
    In the second argument of `($)', namely `fromJSON returnData' 
Failed, modules loaded: none. 

Meine Frage ist nun, wie diese JSON-Zeichenfolge zurück in ein Objekt des Typs "Rectangle" konvertieren?

EDIT 1: Ich änderte meinen Code aufgrund Janos Potecki Antwort und erhalten jetzt die folgende Fehlermeldung:

Couldn't match type `[Char]' with `ByteString' 
    Expected type: ByteString 
     Actual type: String 
    In the second argument of `($)', namely `show $ decode json' 
    In the expression: BS.putStrLn $ show $ decode json 
    In a case alternative: 
     Just json -> BS.putStrLn $ show $ decode json 
Failed, modules loaded: none. 

EDIT 2: Habe ich es zu:

main = do   
    let point = Point 1 2 
    let rectangle = Rectangle 10 20 point 
    let url = "http://localhost:8000/Rectangle/Move/100,200" 
    let opts = defaults & header "Content-Type" .~ ["application/json"] 
    r <- postWith opts url (encode rectangle)  
    let returnData = (r ^? responseBody) >>= decode 
    case returnData of 
    Nothing  -> BS.putStrLn "Error decoding JSON" 
    Just json  -> BS.putStrLn json 

und Jetzt bekomme ich:

No instance for (FromJSON ByteString) 
     arising from a use of `decode' 
    In the second argument of `(>>=)', namely `decode' 
    In the expression: (r ^? responseBody) >>= decode 
    In an equation for `returnData': 
     returnData = (r ^? responseBody) >>= decode 
+1

Die 'fromJSON' Funktion nicht analysieren JSON, es konvertiert nur geparste JSON in eine andere Haskell-Datenstruktur. Sie möchten stattdessen 'decode'. 'ReturnData' ist jedoch kein' ByteString', es ist ein 'Maybe ByteString', also müssen Sie eine Musterübereinstimmung herstellen, verwenden Sie '>> =', oder ein anderes Werkzeug, um 'returnData' als' Nichts' zu behandeln '. In diesem Beispiel sollte 'print (decode = << returnData)' das tun, was Sie wollen. –

Antwort

3

Arbeitslösung

r' <- asJSON =<< postWith opts url (encode rectangle) :: IO Res 
case r' of 
    Nothing  -> print "Error decoding JSON" 
    Just x   -> print x 

Für Leistung würde ich vorschlagen, dass Sie die folgenden zu Ihrem instance ToJSON hinzufügen:

instance ToJSON Point where 
     toEncoding = genericToEncoding defaultOptions 

und das gleiche für Rectangle

+0

Ich habe versucht Ihre Lösung und jetzt bekomme ich einen weiteren Fehler, siehe meine Edit 1 oben – ManzMoody

+0

Entschuldigung, die 'decode' ist natürlich zu viel –

+0

ich änderte es und bekomme jetzt:' Konnte nicht erwartet Typ 'ByteString ' mit tatsächlichem Typ 'Maybe ByteString ' Im ersten Argument von' decode', nämlich 'returnData ' Im Ausdruck: (decode returnData)' – ManzMoody