I have implemented a function (!!=) that given a list and a tuple containing an index in the list and a new value, updates the given list with the new value at the given index.
(!!=) :: [a] -> (Int,a) -> [a]
(!!=) xs (0, a) = a : tail xs
(!!=) [] (i, a) = error "Index not in the list"
(!!=) (x:xs) (i, a) = x : xs !!= (i-1, a)
Being a beginner with the concept of folding I was wondering if there is a way to achieve the same result using foldl or foldr instead?
Thanks a lot in advance.
I'll give you the foldl
version which is easier to understand I think and the easiest / most straight-forward version I can think of.
But please note that you should not use foldl
(use foldl'
: https://wiki.haskell.org/Foldr_Foldl_Foldl') - nor should you use ++
like this (use :
and reverse after) ;)
Anway this is the idea:
(!!=) xs (i, a) = snd $ foldl
(\(j, ys) x -> (j+1, if j == i then ys ++ [a] else ys ++ [x]))
(0, [])
xs
snd
because I only want this in the end)as an exercise you can try to:
:
instead of ++
and a reverse
foldr
zipWith
and rewrite this using this (zipWith (...) [0..] xs
) instead of the fold (this is similar to using a map with index