Как concatMap по всем парам ключ / значение в Aeson.Object с помощью линз

Я дурачился с комбинаторами в Control.Lens.Indexed, особенно _ 1_, но мне не удалось придумать функцию со следующим type-sig, используя _ 2_ lens:

func 

  -- list of key/value pairs, essentially
  :: Aeson.Object                  

  -- function for the concatMap operation to which the 
  -- key (Text) and value is passed
  -> (Text -> Aeson.Value -> [a])  

  -- resultant concatenated list
  -> [a]

person Saurabh Nanda    schedule 28.09.2018    source источник


Ответы (1)


Требуемая функция - _1 _. Также обратите внимание, что members обходит типы с экземпляром AsValue, а для Object такого экземпляра нет, поэтому нам нужно обернуть его в Value.

import qualified Data.Aeson as Aeson
import Control.Lens
import Data.Aeson.Lens
import Data.Text

func :: Aeson.Object -> (Text -> Aeson.Value -> [a]) -> [a]
func obj f = iconcatMapOf members f (Aeson.Object obj)
person András Kovács    schedule 28.09.2018
comment
не могли бы вы объяснить разницу между iconcatMap и iconcatMapOf? - person Saurabh Nanda; 28.09.2018
comment
@SaurabhNanda iconcatMap сворачивает структуру данных с помощью экземпляра FoldableWithIndex. iconcatMapOf сворачивает структуру, но вы можете дополнительно указать способ сворачивания, используя индексированный обход (здесь конкретно геттер). Таким образом, используя iconcatMapOf, вы можете свернуть в обратном порядке, или в любом порядке, или только некоторые элементы, указав другой обход, тогда как с iconcatMap вы можете свернуть только способом по умолчанию (заданным экземпляром класса). - person András Kovács; 28.09.2018
comment
В этом случае у Object и Value нет экземпляров FoldableWithIndex (они не имеют правильного типа для начала), поэтому вы можете сложить их только с помощью настраиваемой складки. - person András Kovács; 28.09.2018