更改第 n 个元素
许多语言中的一个常见操作是分配给数组中的索引位置。在 python 中你可能会:
>>> a = [1,2,3,4,5]
>>> a[3] = 9
>>> a
[1, 2, 3, 9, 5]
lens 包通过 (.~) 运算符提供此功能。虽然与 python 不同的是,原始列表不会发生突变,而是返回一个新列表。
> let a = [1,2,3,4,5]
> a & element 3 .~ 9
[1,2,3,9,5]
> a
[1,2,3,4,5]
element 3 .~ 9 只是一个函数,(&) 运算符是
lens 包,只是反向功能应用。这里是比较常见的功能应用。
> (element 3 .~ 9) [1,2,3,4,5]
[1,2,3,9,5]
在Traversables 的任意嵌套中,赋值再次完美运行。
> [[1,2,3],[4,5,6]] & element 0 . element 1 .~ 9
[[1,9,3],[4,5,6]]
或
> set (element 3) 9 [1,2,3,4,5,6,7]
或者如果你想影响多个元素,你可以使用:
> over (elements (>3)) (const 99) [1,2,3,4,5,6,7]
> [1,2,3,4,99,99,99]
使用列表以外的类型
这不仅限于列表,它还适用于作为 Traversable 类型类实例的任何数据类型。
例如,相同的技术适用于标准的trees
containers 包。
> import Data.Tree
> :{
let
tree = Node 1 [
Node 2 [Node 4[], Node 5 []]
, Node 3 [Node 6 [], Node 7 []]
]
:}
> putStrLn . drawTree . fmap show $ tree
1
|
+- 2
| |
| +- 4
| |
| `- 5
|
`- 3
|
+- 6
|
`- 7
> putStrLn . drawTree . fmap show $ tree & element 1 .~ 99
1
|
+- 99
| |
| +- 4
| |
| `- 5
|
`- 3
|
+- 6
|
`- 7
> putStrLn . drawTree . fmap show $ tree & element 3 .~ 99
1
|
+- 2
| |
| +- 4
| |
| `- 99
|
`- 3
|
+- 6
|
`- 7
> putStrLn . drawTree . fmap show $ over (elements (>3)) (const 99) tree
1
|
+- 2
| |
| +- 4
| |
| `- 5
|
`- 99
|
+- 99
|
`- 99