我想将此行代码map (^?! ix 0) [[0, 1], [4, 5], [9, 1]]
转换为完全使用镜头,因此类似于[[0, 1], [4, 5], [9, 1]] & each . ix 0
。但是,这些类型并不匹配。这样做的正确方法是什么?
答案 0 :(得分:10)
您可以使用
之一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
的作用,并且可以用于非列表的结构。
第二个使用提供的镜头折叠创建结构的列表摘要;虽然它可以用于多种结构,但结果始终是一个列表。
您还可以将each
替换为traverse
(或者,正如@danidiaz指出的那样,稍微更为一般traversed
)。前者适用于许多特殊事物,如元组,而后者适用于任何Traversable
。
答案 1 :(得分:10)
使用folded
:
Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. folded . ix 0
[0,4,9]
适用于任何Foldable
。
另外,如果您打算始终提取第一个元素,那么使用_head
而不是Control.Lens.Cons
的{{1}}遍历可能会更清楚。
ix