I\'m trying to write a function that accepts a string and a list of tuple pairs. I want to search through the list of tuples, and if the first value in the tuple matches the inp
In the base case, if list is empty, it returns Nothing. Then, if first element a of tuple in the head is equal to element x, it returns second element Just b. Else, recursively, it searchs in the tail.
search :: (Eq a) => a -> [(a,b)] -> Maybe b
search _ [] = Nothing
search x ((a,b):xs) = if x == a then Just b else search x xs
You can implement an unsafe version without Maybe:
search :: (Eq a) => a -> [(a,b)] -> b
search _ [] = error "element not found"
search x ((a,b):xs) = if x == a then b else search x xs
Other option is searching a list instead of first ocurrence, then, empty list [] is equivalent to Nothing:
search :: (Eq a) => a -> [(a,b)] -> [b]
search x = map snd . filter ((==x).fst)
find can retrieve the first element satisfying an arbitrary condition, and so you might build your function around it:
-- 'fmap snd' acts on the 'Maybe (a, b)' that 'find' gives back.
search :: Eq a => a -> [(a,b)] -> Maybe b
search a = fmap snd . find ((== a) . fst)
Note that this is exactly the same as lookup. Also, as leftaroundabout points out, 3 (as opposed to Just 3) is not a possible result for a function with a Maybe b result type. You can eliminate the Maybe wrapping when you actually need to use the result using, for instance, the maybe function:
GHCi> :t maybe
maybe :: b -> (a -> b) -> Maybe a -> b
GHCi> (maybe "No x" (("x ~> " ++) . show) . search "x") ([("x", 3), ("z", 5)])
"x ~> 3"
GHCi> (maybe "No x" (("x ~> " ++) . show) . search "x") ([("y", 3), ("z", 5)])
"No x"
Just use a simple map combined with a lambda:
searchMe :: (Eq a) => a -> [(a, b)] -> [Maybe b]
searchMe a li = map (\(x, y) -> if a == x then Just y else Nothing ) li
OP your function, as it is, won't work as you are defining your list parameter as (x : xs), which won't enable you to apply operations to elements of the tuple.