使用镜头作为`map`

yon*_*ong 8 haskell lenses

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

Ørj*_*sen 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]
Run Code Online (Sandbox Code Playgroud)

第一个对应于您使用不安全(^?!)运算符编写的内容,这意味着它可以给出错误.第二个是省略空列表更安全.

它们以不同的方式工作:第一个创建原始结构的修改版本,它更多地与什么相对应map,并且可以在非列表的结构上使用.

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

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

  • @danidiaz不,我的意思是"横越".虽然它不是*来自*镜头,但它被认为是它的重要组成部分. (2认同)

dan*_*iaz 10

用途folded:

Prelude Control.Lens> [[0, 1], [4, 5], [9, 1]] ^.. folded . ix 0
[0,4,9]
Run Code Online (Sandbox Code Playgroud)

适用于任何Foldable.

此外,如果您计划始终提取第一个元素,也许使用_head遍历Control.Lens.Cons而不是更清楚ix.

[[0, 1], [4, 5], [9, 1]] ^.. folded . _head
Run Code Online (Sandbox Code Playgroud)