I'm trying to find if some letter is already used in any string in the list of strings. If yes - choose next letter to compare. If no - return this letter and update the initial list.
To check in the list I'm using:
check:: [String] -> Char -> Char
check s c
| any (elem c) s = check s (next c)
| otherwise = do update s c
return c
But it gives me an error:
Couldn't match type ‘[Char]’ with ‘Char’
Expected type: [String] -> [Char] -> Char
Actual type: [String] -> [Char] -> [Char]
In a stmt of a 'do' block: update s c
My update function has following declaration:
update:: [String] -> Char -> [String]
Is there any correct way to perform 2 actions in the guard otherwise
?
I need to return c in order to use it in another recursive function, which takes as the parameters both Char
c and updated [String]
s
When I had this functions returning only c, without updating the list, there where no errors:
check:: [String] -> Char -> Char
check s c
| any (elem c) s = check s (next c)
| otherwise = c
Any tips are welcome.
Update: My next function is:
next :: Char -> Char
next 'Z' = 'A'
next c = chr (ord c + 1)
And for update I've tried:
update:: [String] -> Char -> [String]
update s c = s ++ [[c]]
The thing is that later on, I need to use [String]
which is the result of update, together with Char
c (result from check) into another function.
That's why, after performing check, I need to return a value, and to update a list with it.
Haskell is a functional language, hence you cannot (should not) think of mutating a data structure, instead a function should return an updated version of that data structure, and whatever else you need. Most common way to do it is returning a tuple of values you need. Here is what you are probably looking for:
check:: [String] -> Char -> (Char, [String])
check s c
| any (elem c) s = check s (next c)
| otherwise = (c, s ++ [[c]])
This way you get "this" letter and updated version of the initial list of String
s.