Невозможно собрать значения из вложенного JSON с помощью линз - PullRequest
3 голосов
/ 04 апреля 2020

Редактировать

Мне удалось получить ответ после нескольких случайных перестановок. Но я до сих пор не понимаю, почему первый работает, а второй нет:

x ^.. (key "conversations") . values . (key "id") . _String

-- vs

x ^@.. (key "conversations") . values . (imap (\ _ v -> v ^? key "id"))

Исходный вопрос

У меня есть JSON со следующей формой:

{
  "conversations":[
    {"id":"abc", ...}, 
    {"id":"abc", ...}, 
    {"id":"abc", ...}, 
    ...
  ]
}

Я пытаюсь получить conversations.*.id, используя следующее выражение ...

x ^@.. (key "conversations") . values . (imap (\ _ v -> v ^? key "id"))

..., что приводит к следующей ошибке компилятора:

    • Couldn't match type ‘Maybe’
                     with ‘Const
                             (base-4.13.0.0:Data.Semigroup.Internal.Endo [(Int, Value)])’
      Expected type: IndexedGetting
                       Int
                       (base-4.13.0.0:Data.Semigroup.Internal.Endo [(Int, Value)])
                       BSL.ByteString
                       Value
        Actual type: Indexed
                       Int
                       Value
                       (Const
                          (base-4.13.0.0:Data.Semigroup.Internal.Endo [(Int, Value)]) Value)
                     -> BSL.ByteString -> Maybe BSL.ByteString

значения кажутся «индексированными обходом элементов массива», а imap - FunctorWithIndex, так почему же это не скомпилируется должным образом? Чего мне не хватает?

PS: я заметил, что задал аналогичный вопрос около 2 лет go. Этот вопрос концептуально одинаков? Я скучаю по основам c понимания линз?

1 Ответ

0 голосов
/ 04 апреля 2020

Мне удалось получить ответ после нескольких случайных перестановок. Но я до сих пор не понимаю, почему первый работает, а второй нет:

x ^.. (key "conversations") . values . (key "id") . _String

-- vs

x ^@.. (key "conversations") . values . (imap (\ _ v -> v ^? key "id"))

imap - это функция отображения, вариант fmap это дает доступ к индексу. Это не opti c, и вы не можете таким образом составить его с другой оптикой. Хотя существует индексированная версия сеттера imap, imapped, это все равно не поможет, поскольку для (^..) требуется сгиб, а (^@..) - индексированный сгиб. key, с другой стороны, устанавливает обход, который можно использовать для получения определенных свойств c так, как вы планировали, поскольку все обходы являются сгибами.

...