Learn You a Haskell offers the findKey
function:
Here's the book's implementation:
findKey :: (Eq k) => k -> [(k,v)] -> v
findKey key xs = snd . head . filter (\(k,v) -> key == k) $ xs
I implemented it with $
:
findKey' :: (Eq k) => k -> [(k,v)] -> v
findKey' k xs = snd $ head $ filter ((== k) . fst) xs
As far as I can tell, it's a stylistic choice here to select .
over $
?
Lastly, is there a way to write findKey
such that the [(k,v)]
is curried & thus not required in the signature of findKey key xs
?
3 Answers 3
Both are fine, and it's a matter of choice.
The first definition, being a composition of functions, treats snd . head . filter (\(k, v) -> key == k)
as one big function. It can therefore be transformed more easily into point-free style, if you like that kind of thing.
findKey'' :: (Eq k) => k -> ([(k, v)] -> v)
findKey'' key = snd . head . filter (\(k,v) -> key == k)
It's a stylistic choice, yes.
is there a way to write
findKey
such that the[(k,v)]
is curried & thus not required in the signature offindKey key xs
?
If you mean a way to avoid having pairs in the type: no, if the function operates on a list of pairs, pairs must appear in its type.
If you mean a way to filter with a curried function instead of one taking a tuple, uncurry
is the closest approximation:
filter (uncurry \k v -> k == key) xs
Note that the Prelude supplies a predefined function much like findKey
:
lookup :: Eq a => a -> [(a, b)] -> Maybe b.
In case you were working with functions it turns out to be identical. But the $ operator is a generalization of the . operator, I mean, the dot operator (.) must be implemented with functions, but the dollar operator ($) is universal. The $ operator is implemented to avoid using parenthesis. A very simple and elegant rule to memorize its functionality
sum :: (Eq a) => a -> a -> a
sum a b = (a + b)
versus
sum2 :: (Eq a) => a -> a -> a
sum2 a b = $ a + b
Explore related questions
See similar questions with these tags.