The replaceAtMatrix function should take in a tuple (Int,Int) that decides what position is the value that needs to be changed, a value to be changed to, and the List in List [[a]].
If the tuple’s values exceed the lists length the original [[a]] needs to be returned.
replaceAtList :: Int -> a -> [a] -> [a]
replaceAtList _ _ [] = []
replaceAtList 0 a (_:xs) = a:xs
replaceAtList number a (x:xs)
| number < 0 = x:xs
| number > (length (x:xs)-1) = x:xs
| otherwise = x : replaceAtList (number-1) a xs
replaceAtMatrix :: (Int,Int) -> a -> [[a]] -> [[a]]
replaceAtMatrix _ _ [] = []
replaceAtMatrix (0,num2) a (x:xs) = replaceAtList num2 a x : xs
replaceAtMatrix (num1,num2) a (x:xs)
| num1 < 0 = x:xs
| num1 > (length (x:xs)-1) = x:xs
| num2 < 0 = x:xs
| num2 > (length (x:xs)-1) = x:xs
| otherwise = x : replaceAtMatrix (num1-1,num2) a xs
There are test for which I checked, and it passes most of them, but there’s one where it goes in an infinite cycle. Here’s the tests that work.
replaceAtMatrix (-1,0) 'A' ["bcd","lds","rtz"] == ["bcd","lds","rtz"]
replaceAtMatrix (0,0) 'A' ["bcd","lds","rtz"] == ["Acd","lds","rtz"]
replaceAtMatrix (2,0) 'A' ["bcd","lds","rtz"] == ["bcd","lds","Atz"]
replaceAtMatrix (3,0) 'A' ["bcd","lds","rtz"] == ["bcd","lds","rtz"]
replaceAtMatrix (2,2) 'A' ["bcd","lds","rtz"] == ["bcd","lds","rtA"]
And here’s the one that doesn’t.
Edit: I just realized it’s probaly beacuse I use length on an infinite list. How can I rewrite it without using length?
take 5 (replaceAtMatrix (1,2) 100 [[1..],[1,11..],[],[12,13,14]] !! 1) == [1,11,100,31,41]
Without the guard, I get a variable not in scope error.
replaceAtList :: Int -> a -> [a] -> [a]
replaceAtList _ _ [] = []
replaceAtList 0 a (_:xs) = a:xs
replaceAtList number a (x:xs) = x : replaceAtList (number-1) a xs
replaceAtMatrix :: (Int,Int) -> a -> [[a]] -> [[a]]
replaceAtMatrix _ _ [] = []
replaceAtMatrix (0,num2) a (x:xs) = replaceAtList num2 a x : xs
replaceAtMatrix (num1,num2) a (x:xs) = x : replaceAtMatrix (num1-1,num2) a xs
>Solution :
Don’t use length. This will error on infinite lists: you do not need this: in case the number > length somelist, eventually it will reach the end of the list:
replaceAtList :: Int -> a -> [a] -> [a]
replaceAtList _ _ [] = []
replaceAtList n _ xs
| n < 0 = xs
replaceAtList 0 a (_:xs) = a:xs
replaceAtList number a (x:xs) = x : replaceAtList (number-1) a xs
replaceAtMatrix :: (Int,Int) -> a -> [[a]] -> [[a]]
replaceAtMatrix _ _ [] = []
replaceAtMatrix (m, _) _ xs
| m < 0 = xs
replaceAtMatrix (0,num2) a (x:xs) = replaceAtList num2 a x : xs
replaceAtMatrix (num1,num2) a (x:xs) = x : replaceAtMatrix (num1-1,num2) a xs