Home > front end >  How to fix a list to character matching error in Haskell?
How to fix a list to character matching error in Haskell?

Time:10-10

I am trying to write a function that finds a pair by matching its first component and returns that pair's second component. When one tries to look up a character that does not occur in the cipher key, the function should leave it unchanged. Examples:

ghci> lookUp 'B' [('A','F'), ('B','G'), ('C','H')]
'G'
ghci> lookUp '9' [('A','F'), ('B','G'), ('C','H')]
'9'

I have a cipher key that I am not sure whether would help, but here it is:

alphabet = ['A'..'Z']

makeKey :: Int -> [(Char, Char)]
makeKey k = zip alphabet (rotate k alphabet)

That outputs something like this:

ghci> makeKey 5
[('A','F'),('B','G'),('C','H'),('D','I'),('E','J'),('F','K'),
('G','L'),('H','M'),('I','N'),('J','O'),('K','P'),('L','Q'),
('M','R'),('N','S'),('O','T'),('P','U'),('Q','V'),('R','W'),
('S','X'),('T','Y'),('U','Z'),('V','A'),('W','B'),('X','C'),
('Y','D'),('Z','E')]

This is my code so far:

lookUp :: Char -> [(Char, Char)] -> Char
lookUp a xs = [ c | (b,c) <- xs, b == a ]

When I try to run it, it produces a list and character mismatch error. How do I fix this?

CodePudding user response:

With list comprehension you return a list of items. If you thus implement this as:

lookUp :: Char -> [(Char, Char)] -> [Char]
lookUp a xs = [ c | (b,c) <- xs, b == a ]

you will retrieve a list of Characters (a String) which contains the second item c of the 2-tuples, given the first item b of that 2-tuple matches with the query a.

But you do not want to retrieve a list, but only the first match, or the same item given the item is not in the list of 2-tuples.

We can implement this for example with recursion where we enumerate over the elements of the list and if we find the given item, we return the second item. If no 2-tuple can be found with as first item the item we are looking for, we return the item we are looking for:

lookUp :: Eq a => a -> [(a, a)] -> a
lookUp query = go
    where go [] = …  -- (1)
          go ((xa, xb) : xs)
              | query = xa = …  -- (2)
              | otherwise = …  -- (3)

where you need to fill in the parts. For the third case, you will need to recurse on the tail xs of the list.

  • Related