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.