Changing the nth item
A common operation in many languages ββis the assignment of an indexed position in an array. In python you can:
>>> a = [1,2,3,4,5] >>> a[3] = 9 >>> a [1, 2, 3, 9, 5]
The lens package provides this functionality to the operator (.~) . Although, unlike python, the original list is not mutated, the new list is more likely to return.
> 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 is just a function and operator (&) , part of the lens package is just an application with an inverse function. Here it is with a more common feature application.
> (element 3 .~ 9) [1,2,3,4,5] [1,2,3,9,5]
The assignment works fine again with Traversable s arbitrary nesting.
> [[1,2,3],[4,5,6]] & element 0 . element 1 .~ 9 [[1,9,3],[4,5,6]]
or
> set (element 3) 9 [1,2,3,4,5,6,7]
Or, if you want to use several elements that you can use:
> over (elements (>3)) (const 99) [1,2,3,4,5,6,7] > [1,2,3,4,99,99,99]
Work with other types of lists
This is not limited to lists, however, it will work with any data type that is an instance of the Traversable typeclass.
Take, for example, the same technique that works on container trees.
> 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