编辑

尝试了几次随机排列后,我设法得到了答案。但是我仍然不明白前者为什么起作用,而后者却不起作用:

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


values似乎是“对数组元素的索引遍历”,而imap似乎是FunctorWithIndex,那么为什么它不按预期构成?我想念什么?

PS:我注意到大约2年前我曾问过similar question。这个问题在概念上是否相同?我是否缺少对镜片的一些基本了解?

最佳答案

经过几次尝试,我设法得到了答案
排列。但是我仍然不明白前者为什么起作用,但是
后者没有:

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

-- vs

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



imap是映射函数,是fmap的变体,可以访问索引。它不是光学元件,因此您无法以这种方式与其他光学元件组合。尽管存在imapimapped的索引设置器版本,但它仍然无济于事,因为(^..)需要折叠,而(^@..)是索引折叠。另一方面,key设置了一个遍历,该遍历可用于以您想要的方式检索特定属性,因为所有遍历都是折叠。

关于haskell - 无法使用镜头从嵌套JSON收集值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61033052/

10-12 19:47