Извлечение текста из значения JSON String Text без сопоставления с образцом - PullRequest
0 голосов
/ 28 декабря 2018

Вот определение для значения Json:

-- | A JSON value represented as a Haskell value.
data Value = Object !Object
           | Array !Array
           | String !Text
           | Number !Scientific
           | Bool !Bool
           | Null
             deriving (Eq, Show)

let value = String "myValue"
looking for => fromString value == "myValue" ??
fromString :: Value -> Text

Я ищу функцию, подобную той, в которой я мог бы получить текст из String без какого-либо сопоставления с образцом, очевидно, эта функция будет небезопасной.... fromString, например fromJust в Data.Maybe, например ... Что-то в Data.Lens.Aeson?

1 Ответ

0 голосов
/ 29 декабря 2018

Как подразумевает Томас М. Дюбюссон в вышеприведенном комментарии, это звучит как XY Проблема .Тем не менее, я сделаю все возможное, чтобы, тем не менее, рассмотреть эти особенности.

Технически , вы можете тривиально написать функцию с типом Value -> Text, хотя это требует сопоставления с образцом.Я понимаю, что OP запрашивает функцию без сопоставления с образцом, но, пожалуйста, прочитайте:

-- Warning: UNSAFE!
fromString :: Value -> Text
fromString (String s) = s

Такая функция компилируется, но небезопасна!

*Q53961314 Q53961314> fromString $ String "myValue"
"myValue"
*Q53961314 Q53961314> fromString $ Number 42
"*** Exception: Non-exhaustive patterns in function fromString

Хотя он работает для String значений, он дает сбой для любого другого типа значения.Хотя технически возможно писать и компилировать небезопасные функции, подобные описанным выше, AFAICT не считается идиоматическим Haskell.

Лучшей альтернативой является безопасная функция, которая возвращает Maybe Text.Это все еще легко написать, используя сопоставление с образцом:

fromStringSafe :: Value -> Maybe Text
fromStringSafe (String s) = Just s
fromStringSafe _ = Nothing

Эта функция является общей:

*Q53961314 Q53961314> fromStringSafe $ String "myValue"
Just "myValue"
*Q53961314 Q53961314> fromStringSafe $ Number 42
Nothing

Если вы не хотите писать такую ​​функцию самостоятельно, но предпочитаете использовать lens-aeson , вы можете использовать призму _String:

Prelude Data.Aeson Data.Aeson.Lens Control.Lens> String "myValue" ^? _String
Just "myValue"

Как вы можете сказать, это также безопасно, так как ^? _String возвращает Maybe Text:

Prelude Data.Aeson Data.Aeson.Lens Control.Lens> Bool True ^? _String
Nothing
Prelude Data.Aeson Data.Aeson.Lens Control.Lens> Number 42 ^? _String
Nothing

Если вы действительно, действительно хотите небезопасную функцию, вы можете использовать ^?! _String:

Prelude Data.Aeson Data.Aeson.Lens Control.Lens> String "myValue" ^?! _String
"myValue"

Это, что неудивительно, небезопасно:

Prelude Data.Aeson Data.Aeson.Lens Control.Lens> Number 42 ^?! _String
"*** Exception: (^?!): empty Fold
CallStack (from HasCallStack):
  error, called at src\\Control\\Lens\\Fold.hs:1285:28 in lens-4.17-7m3etWEBj0P3172qv7LEG9:Control.Lens.Fold
  ^?!, called at <interactive>:9:1 in interactive:Ghci3

Интересно, почему вы спрашиваете о такой функциональности?Есть ли конкретная проблема, которую вы пытаетесь решить с помощью Aeson, с которой мы можем помочь?

...