Haskell 无法使用镜头从嵌套JSON收集值 编辑

Haskell 无法使用镜头从嵌套JSON收集值 编辑,haskell,haskell-lens,aeson,Haskell,Haskell Lens,Aeson,在尝试了几次随机排列之后,我终于得到了答案。但我仍然不明白为什么前者有效,但后者无效: x ^.. (key "conversations") . values . (key "id") . _String -- vs x ^@.. (key "conversations") . values . (imap (\ _ v -> v ^? key "id")) x ^.. (key "conversations") . values . (key "id") . _String -

在尝试了几次随机排列之后,我终于得到了答案。但我仍然不明白为什么前者有效,但后者无效:

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

-- vs

x ^@.. (key "conversations") . values . (imap (\ _ v -> v ^? key "id"))
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", ...}, 
    ...
  ]
}
我正在尝试使用以下表达式获取
对话。*.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
,那么为什么这不能像预期的那样组合呢?我错过了什么

附言:我注意到大约两年前我问了一个问题。这个问题在概念上是相同的吗?我是不是对镜片缺乏一些基本的了解

在尝试了几次随机选择后,我终于得到了答案 置换。但我还是不明白为什么前者有效,但是 后者没有:

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

-- vs

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

-- vs

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

是一个映射函数,是
fmap
的变体,可访问索引。它不是光学元件,所以你不能用这种方式将它与其他光学元件组合。虽然有一个索引setter版本的
imap
,但它仍然没有帮助,因为
(^..)
需要折叠,而
(^@..)
需要索引折叠,另一方面,设置一个遍历,该遍历可用于以您想要的方式检索特定属性,因为所有遍历都是折叠的。

您能解释一下为什么
imap
不能按我希望的方式组合吗?它是一种“常规”功能,即与镜头无关吗?@SaurabhNanda是的,部分问题在于
imap
没有正确的类型。有一个索引setter版本的
imap
imap
(即
imap
映射到普通
fmap
),但它仍然不能做您想要的事情。setter只能修改目标,不能检索它们。因为您正试图使用
(^..)
检索元素,所以setter不会有帮助:您需要折叠<代码>键“id”是一个遍历,每个遍历都是一个折叠,因此它可以正常工作。