Haskell 使用镜头作为地图`

Haskell 使用镜头作为地图`,haskell,lenses,Haskell,Lenses,我想将这行代码映射(^?!ix 0)[[0,1],[4,5],[9,1]]转换为完全使用镜头,所以类似[0,1],[4,5],[9,1]&的东西。ix 0。但是,类型不匹配。正确的方法是什么?您可以使用 Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] & each %~ (^?! ix 0) [0,4,9] Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. each . ix 0

我想将这行代码
映射(^?!ix 0)[[0,1],[4,5],[9,1]]
转换为完全使用镜头,所以类似
[0,1],[4,5],[9,1]&的东西。ix 0
。但是,类型不匹配。正确的方法是什么?

您可以使用

Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] & each %~ (^?! ix 0)
[0,4,9]
Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. each . ix 0
[0,4,9]
第一个与您编写的内容完全对应,使用不安全的
(^?!)
运算符,这意味着它可能会给出错误。第二种方法是省去空列表,这样更安全

它们的工作方式有些不同:第一种是创建原始结构的修改版本,它更符合
map
的功能,并且可以在非列表的结构上使用

第二个使用提供的镜头折叠创建结构的列表摘要;虽然它可以用于多种结构,但结果总是一个列表


您还可以用
遍历
(或者,正如@danidiaz所指出的,在本例中,更一般的
遍历
)来替换每个
。前者适用于许多特殊的事物,如元组,而后者适用于任何可遍历的

使用
折叠的

Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. folded . ix 0
[0,4,9]
适用于任何可折叠的

另外,如果您计划总是提取第一个元素,那么使用
控件.Lens.Cons中的
遍历而不是
ix
可能会更清楚

[[0, 1], [4, 5], [9, 1]] ^.. folded . _head

也许你的意思是从
Control.Lens.Traversal
遍历
,而不是
traverse
?@danidiaz-Nope,我的意思是
traverse
。虽然它不是来自镜头,但它被认为是镜头的一个重要部分。@danidiaz哦,我明白了,两者都在这里工作。似乎
traversed
更一般,允许索引。我不知道可以直接使用
traverse
。但从类型上看,我应该是。