Home > Blockchain >  haskell comprehension list, compare string with list and create string list with values, from list
haskell comprehension list, compare string with list and create string list with values, from list

Time:11-05

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"]
  • Related