2

I have an algebraic data type called Person looks like this:

data Person = 
   Person { firstName :: String
          , lastName  :: String
          , height    :: Float
          , age       :: Int
          } deriving (Show, Eq)

I also have a list of Person filled with various information about people, now say I want to return all the data of one specific Person based on firstName alone, how would I do that?

Like search through all the firstNames stored in the list, and then returning either Just Person if the query matches or Nothing if there isn't any match

2 Answers 2

4

You can use filter to return a list that contains all the Person with a given condition on firstName.

For instance:

filter (\x -> firstName x == "John") xs

where xs contains the list of Person. This will return an empty list ([]) if no Person matches the criteria.

Sign up to request clarification or add additional context in comments.

2 Comments

If you're only interested in the first match, you can use Data.Maybe.listToMaybe on the filtered list.
... or you can use Data.List.find.
1

Very simply, you could write a custom lookup function:

lookupBy :: Eq b => (a -> b) -> [a] -> b -> Maybe a
lookupBy _ [] _ = Nothing
lookupBy f (x:xs) key = if f x == key then Just x else lookupBy f xs key

Then you could use it as

main = do
    let people = [Person "John" "Doe" 68 30, Person "Jane" "Smith" 63 28]
    print $ lookupBy firstName people "Jane"
    print $ lookupBy lastName  people "Doe"
    print $ lookupBy age       people 29
    print $ lookupBy height    people 63

This would print

Just (Person {firstName="Jane", lastName="Smith", height=63, age=28})
Just (Person {firstname="John", lastName="Doe", height=58, age=30})
Nothing
Just (Person {firstName="Jane", lastName="Smith", height=63, age=28})

(assuming that it compiles, I have not run this code but it should work).


If you want to choose on whether you get a single item or a list of matching items, you could do

import Data.Maybe (listToMaybe)

lookupAllBy :: Eq b => (a -> b) -> [a] -> b -> [a]
lookupAllBy f xs key = filter (\x -> f x == key) xs

lookupBy :: Eq b => (a -> b) -> [a] -> b -> Maybe a
lookupBy f xs key = listToMaybe $ lookupAllBy f xs key

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.