(..) Но следующее не работает
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
происходит вызов 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
В принципе, я хотел бы знать, каков будет правильный способ декодировать тип суммы, такой как атрибуты, в этом случае
Ваш подход мне подходит. Это дает вам полный контроль над процессом кодирования / декодирования. Это может быть подвержено ошибкам, хотя ...
Вы можете попробовать и использовать полностью универсальное решение, например purescript-argounaut-generic
.
Вы также можете попробовать другой общий подход и использовать purescript-simple-json
. Я не смог найти пример для обработки общих сумм - здесь только enum как тип, закодированный / декодированный: https://www.reddit.com/r/purescript/comments/7b5y7q/some_extra_examples_of_simplejson_usage/. Вы всегда можете спросить у Джастина Ву предложения - он действительно отзывчивый автор: -)
Я еще не использовал purescript-codec-argonaut
, но это должно помочь вам минимизировать дублирование, связанное с определениями кодирования и декодирования. При таком подходе вы по-прежнему отвечаете за определение всего вручную, я думаю.
Вот интересный пост, который я считаю наиболее актуальным, если у вас нет PureScript на обоих концах провода (потребитель и производитель) @garyb о недостатках родовых кодеков: http://code.slipthrough.net/2018/03/13/thoughts-on-typeclass-codecs/
У вас есть PureScript на обоих концах провода?