Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set value in nth element in a Haskell list?

Tags:

list

haskell

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']?

like image 300
jason Avatar asked Mar 20 '13 17:03

jason


People also ask

How do you find the nth element of a list?

Use list indexing to get the nth element of a list. Use list indexing syntax list[index] with n - 1 as index , where n represents a value's placement in the list, to retrieve the respective nth element of a list.

How do I append in Haskell?

Haskell uses the ++ operator to append lists. OCaml uses the @ operator to append lists. Other languages use the + or ++ symbols for nondestructive string/list/array concatenation.

What does ++ mean in Haskell?

The ++ operator is the list concatenation operator which takes two lists as operands and "combine" them into a single list.


1 Answers

Changing the nth element

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 Traversables.

> [[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]

Working with types other then lists

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
like image 75
Davorak Avatar answered Oct 19 '22 10:10

Davorak