I know that xs!!n gives me nth element in a list, but I don't know how to edit nth element in that list. Can you tell me how can I edit nth element in a list or give a hint at least? For example how can I make the second element 'a' an 'e' in this : ['s','t','a','c','k'] ? Thanks.
A common operation in many languages is to assign to an indexed position in an array. In python you might:
>>> a = [1,2,3,4,5]
>>> a[3] = 9
>>> a
[1, 2, 3, 9, 5]
The
lens package gives this functionality with the (.~)
operator. Though unlike in python the original list is not mutated, rather a new list is returned.
> 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 the (&)
operator, part of the
lens package, is just reverse function application. Here it is with more common function application.
> (element 3 .~ 9) [1,2,3,4,5]
[1,2,3,9,5]
Assignment again works perfectly fine with arbitrary nesting of Traversable
s.
> [[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 effect multiple elements you can use:
> over (elements (>3)) (const 99) [1,2,3,4,5,6,7]
> [1,2,3,4,99,99,99]
This is not just limited to lists however, it will work with any datatype that is an instance of the Traversable typeclass.
Take for example the same technique works on trees form the standard containers package.
> 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