我正在使用purescript-agronauth库手动将以下类型编码和解码为json并返回。但是以下方法不起作用
data Attributes
= TextAlignment TextAlign
| TextScale String
| LineHeight String
instance encodeAttributes :: EncodeJson Attributes where
encodeJson r =
case r of
(TextAlignment p) ->
"key" := (fromString "text-align")
~> "value" := p
(TextScale p) ->
"key" := (fromString "font-size")
~> "value" := p
(LineHeight p) ->
"key" := (fromString "line-height")
~> "value" := p
instance decodeElementAttributes :: DecodeJson ElementAttributes where
decodeJson json = do
obj <- decodeJson json
key <- getField obj "key"
value <- getField obj "value"
case key of
"text-align" -> Right $ TextAlignment value
"font-size" -> Right $ TextScale value
"line-height" -> Right $ LineHeight value
_ -> Left "Unkown element property"
data TextAlign
= LeftAlign
| RightAlign
| CenterAlign
| Justify
instance encodeTextAlign :: EncodeJson TextAlign where
encodeJson r =
case r of
LeftAlign -> fromString "left"
RightAlign -> fromString "right"
CenterAlign -> fromString "center"
Justify -> fromString "justify"
instance decodeTextAlign :: DecodeJson TextAlign where
decodeJson obj = do
case toString obj of
Just "left" -> Right LeftAlign
Just "right" -> Right RightAlign
Just "center" -> Right CenterAlign
Just "justify" -> Right Justify
Just _ -> Left "Unknown alignment"
Nothing -> Left "Unknown alignment"
这会出现以下错误
Could not match type
TextAlign
with type
String
while checking that type t0
is at least as general as type String
while checking that expression value
has type String
in value declaration decodeElementAttributes
where t0 is an unknown type
基本上,我想知道在这种情况下解码诸如属性之类的Sum类型的正确方法是什么
答案 0 :(得分:1)
(..)但以下操作无效
TLDR;这应该起作用:
instance decodeElementAttributes :: DecodeJson Attributes where
decodeJson json = do
obj <- decodeJson json
key <- getField obj "key"
case key of
"text-align" -> TextAlignment <$> getField obj "value"
"font-size" -> TextScale <$> getField obj "value"
"line-height" -> LineHeight <$> getField obj "value"
_ -> Left "Unkown element property"
让我们跳入编译器页面片刻,尝试推断value
类型。
在decodeJson
的monadic块中,有一个对getField
的调用:
value <- getField obj "value"
getField
在其返回类型上是多态的:
getField :: forall a. DecodeJson a => Object Json -> String -> Either String a
因此,仅凭此调用,我们就无法猜测value
的类型。我们需要更多信息/上下文。
但幸运的是,下面几行我们可以找到value
的用法,它为我们提供了一些解决方案:
"text-align" -> Right $ TextAlignment value
因此,请确保我们必须将value
键入为TextAlign
,因为TextAlignment
构造函数需要这样的参数。
但是,请稍候...在value
的另一行下面:
"font-size" -> Right $ TextScale value
,这里有一个问题,因为这告诉我们value
同时具有类型String
和... TextAlign
...
除了向世界介绍我们的发现,我们别无选择:
Could not match type
TextAlign
with type
String
基本上,我想知道在这种情况下解码诸如属性之类的Sum类型的正确方法是什么
您的方法对我来说还可以。它使您可以完全控制编码/解码过程。但这可能很容易出错...
您可以尝试使用purescript-argounaut-generic
之类的通用解决方案。
您还可以尝试使用其他通用方法并使用purescript-simple-json
。我找不到用于通用和处理的示例-这里只是枚举,如类型的编码/解码:https://www.reddit.com/r/purescript/comments/7b5y7q/some_extra_examples_of_simplejson_usage/。您可以随时向贾斯汀·胡(Justin Woo)寻求建议-他是一位反应灵敏的作家:-)
我还没有使用purescript-codec-argonaut
,但是它应该可以帮助您最大程度地减少与编码和解码定义有关的重复。我认为,采用这种方法,您仍然需要手动定义所有内容。
这是一个有趣的帖子,如果您在@garyb的两端(消费者和生产者)都没有PureScript关于通用编解码器的缺点,我认为这是最相关的:http://code.slipthrough.net/2018/03/13/thoughts-on-typeclass-codecs/
导线的两端是否都装有PureScript?