8

我想将这行代码转换map (^?! ix 0) [[0, 1], [4, 5], [9, 1]]为完全使用镜头,例如[[0, 1], [4, 5], [9, 1]] & each . ix 0. 但是,类型不匹配。这样做的正确方法是什么?

4

2 回答 2

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]

第一个恰好对应于您使用 unsafe(^?!)运算符编写的内容,这意味着它可能会出错。第二个更安全,因为省略了空列表。

它们的工作方式有些不同:第一个创建原始结构的修改版本,它与map所做的更对应,它可以用于非列表的结构。

第二个使用提供的镜头折叠创建结构的列表摘要;尽管它可以与多种结构一起使用,但结果始终是一个列表。

您也可以在此替换eachtraverse(或者,正如@danidiaz 指出的,稍微更一般的traversed)。前者适用于元组等许多特殊事物,而后者适用于任何Traversable.

于 2014-11-01T07:16:43.403 回答
10

使用folded

Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. folded . ix 0
[0,4,9]

适用于任何Foldable.

此外,如果您计划始终提取第一个元素,那么使用_head遍历 fromControl.Lens.Cons而不是ix.

[[0, 1], [4, 5], [9, 1]] ^.. folded . _head
于 2014-11-01T07:20:35.640 回答