I am new haskell. I want always check the first element from the string and compare the string with Char value from the list. So firstly I will compare "H" with 'E', then "H" with 'F', then "H" with 'G', and last "H" with 'H'. And if "H" = 'H' so I want add to my output string value of list element, in my case for 'H' it is "GG". But If all four are not equal so I want add to list current character in my case "A". So I want my output to look like this ["GG","A","GG","A"] Do you know some solution ?
My code:
findc :: String -> [(Char, String)] -> [String]
findc str list =
let filtered = [ if inputChar `elem` [(str !! num)] then decodedValue else if inputChar /= (str !! num) then [(str !! num)] else [] | num<-[0..(length str)-1],(inputChar,decodedValue) <- list]
in filtered
input:
findc "HAHA" [('E', "AB"), ('F', "CD"), ('G', "EF"), ('H', "GG")]
bad output:
["H","H","H","GG","A","A","A","A","H","H","H","GG","A","A","A","A"]
CodePudding user response:
Your function is using a list comprehension with effectively nested loops. It loops over the indices of the string and then over the elements in the list of tuples you've passed in. Both contain 4 elements, so it's natural that your list comprehension iterates 16 times and you end up with 16 elements in your incorrect output.
A simpler, correct approach
[(Char, String)]
describes a lookup table.
Fortunately, Haskell gives us the lookup
function.
:ghci> :t lookup
lookup :: Eq a => a -> [(a, b)] -> Maybe b
ghci> tbl = [('E', "AB"), ('F', "CD"), ('G', "EF"), ('H', "GG")]
ghci> lookup 'H' tbl
Just "GG"
ghci> lookup 'A' tbl
Nothing
Now, you just need to map this to your string in a list comprehension, handling the Just
case differently from the Nothing
case.
ghci> [case lookup ch tbl of {Just s -> ...; Nothing -> ...} | ch <- "HAHA"]
["GG","A","GG","A"]
Using Data.Maybe.maybe
Unsurprisingly the Data.Maybe library has fucntions for dealing with Maybe
values like those returned by lookup
.
case expr1 of { Just x -> expr2; Nothing -> expr3 }
Can be expressed as:
maybe expr3 (\x -> expr2) expr1
So we can write:
ghci> [maybe ... ... $ lookup ch tbl | ch <- "HAHA"]
["GG","A","GG","A"]