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 Char
acters (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.