I'm teaching myself Haskell, and while it was a most enlightening experience so far, I find some things that are easily done in C family of languages still a mystery. So, here is my very basic problem. I want a function to extract the tuples with a certain field equal to a given value. So far I have this code
withJob :: [(String, String, String)] -> String -> [String]
withJob [] _ = []
withJob ((_,_,x):xs) job
| job == x = x:(withJob xs job)
| otherwise = (withJob xs job)
users :: [(String, String, String)]
users = [("Jack", "22", "Programmer"), ("Mary", "21", "Designer"), ("John", "24", "Designer")]
When called like this users 'withJob' "Programmer"
it outputs ["Programmer"]
but I would like it to output [("Jack", "22", "Programmer")]
, however I don't know how to access the tuples and not the job(x
) in job == x = x:(withJob xs job)
Use @
-patterns for that:
withJob :: [(String, String, String)] -> String -> [(String, String, String)]
withJob [] _ = []
withJob (t@(_,_,x):xs) job
| job == x = t : withJob xs job
| otherwise = withJob xs job
To expand what @Ingo was getting at: It would be more idiomatic Haskell to write:
jobField :: (String, String, String) -> String
jobField (_, _, j) = j
withJob :: [(String, String, String)] -> String -> [(String, String, String)]
withJob xs job = filter (\x -> jobField x == job) xs
We might go further:
data Person = Person { pName :: String, pAge :: Int, pJob :: String }
filterbyJob :: String -> [Person] -> [Person]
filterbyJob job xs = filter (\p -> pJob p == job) xs
And even then:
filterbyJob :: String -> [Person] -> [Person]
filterbyJob job = filter (\p -> pJob p == job)
Or even:
filterbyJob :: String -> [Person] -> [Person]
filterbyJob job = filter ((== job) . pJob)
At this point, unless one is going to use filterByJob
an awful lot, it probably provides no real value beyond just writing the filter ((== job) . pJob)
where you need it!
The point of this exercise is that there is a powerful function filter
that one can just make use of, rather than rewriting that pattern of code each time. Not only does it save you time and code, but by reusing a known function, you make the code easier to understand by future programmers (including your future self!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With