1

タイプの値をパッケージDistribution.PackageDescription.FlagNameのを使用してJSONオブジェクトに変換する必要がありText.JSONます。 私は次のアプローチに行き着きました: json

instance JSON FlagName where
    showJSON (FlagName n) = makeObj [ ("FlagName", showJSON n) ]
    readJSON object = do
        obj <- readJSON object
        flag <- valFromObj "FlagName" obj
        return flag

値をエンコードして再度デコードしようとすると、次のようになります。

> showJSON (FlagName "foo")  
JSObject (JSONObject {fromJSObject = [("FlagName",JSString (JSONString {fromJSString = "foo"}))]})  
> readJSON (showJSON (FlagName "foo")) :: Result FlagName  
Error "Unable to read JSObject"

エラーはその行にあると思います: Haskellにインスタンスの関数obj <- readJSON object
を使用させるにはどうすればよいですか?readJSONJSON String

更新:私は今ややハックな解決策を見つけました:

instance JSON FlagName where
    showJSON (FlagName n) = makeObj [ ("FlagName", showJSON n) ]

    readJSON object = do
        obj <- readJSON (showJSON (FlagName "foo")) :: Result (JSObject JSValue)
        let maybeFlagName = lookup "FlagName" $ fromJSObject obj
        maybe (fail "Not a FlagName object") (\jsn -> liftM FlagName $ (readJSON jsn :: Result String)) maybeFlagName

誰かがもっとエレガントな解決策を思いついたら、それをいただければ幸いです...

4

2 に答える 2

2

わかりました、私は自分で答えを見つけました:それ自体ではなく(すなわち)
valFromObjの名前を返します。FlagNameStringFlagName

instance JSON FlagName where
    showJSON (FlagName n) = makeObj [ ("FlagName", showJSON n) ]
    readJSON object = do
        obj <- readJSON object
        n <- valFromObj "FlagName" obj
        return $ FlagName n
于 2012-09-05T21:05:18.347 に答える
1

オブジェクトがのない場合に処理できるように、パターンマッチングを行うことをお勧めしますJSObject。失敗する代わりに、他のことをすることができます。import Control.Applicativeを使用する必要があります<$>。私はそのようなものに適用可能な構文が好きです。

 instance JSON FlagName where
     showJSON (FlagName n) = makeObj [ ("FlagName", showJSON n) ]
     readJSON (JSObject obj) = FlagName <$> valFromObj "FlagName" obj
     readJSON _ = fail "unknown object"
于 2012-09-06T04:28:28.457 に答える