Reputation: 29
I'm doing an exercise to practice for my exam tomorrow.
The text tells me to implement a database to a library, to define Item
s that can be books or magazines. To each book I save the Name + Author. To each Magazine
I save the name:
data Item = Book String String
| Magazine String
deriving(Show)
data Requisition = Req String Item
type Database = [Requisition]
exDB :: Database
exDB = [Req "John" (Book "PF" "HS"),Req "Jay"(Book "Apple" "Steve Jobs"),Req "Francis"(Magazine "Forbes")]
books :: Database -> String -> [Item]
books db name = {-- what's next?-}
Now, I need to create a function named books :: Database -> String -> [Item]
, that searches by name on my database and gives me the books that person requested.
how do I do this?
Upvotes: 0
Views: 86
Reputation: 71070
books db name = [... | Req n b@(Book _ _) <- db, n==name]
With list comprehensions, mismatched items are just skipped over. Patterns may be nested.
Upvotes: 1
Reputation: 54058
This is fairly straightforward using the filter
function:
filter :: (a -> Bool) -> [a] -> [a]
It takes a condition to apply to each element of a list, then returns the list of all elements that meet that condition. In your case, you want to look up what books have been requested by a given person. You can break this down into two problems:
Requisition
listTo solve the first, we say
requestsFromPerson :: Database -> String -> Database
requestsFromPerson db name = filter matchesName db
where
matchesName (Req name' item) = name == name'
The second step can also be done with filter
, but I'm going to let you fill in the implementation
onlyBooks :: Database -> Database
onlyBooks db = filter ??? db
Then you can combine these two:
books db name = onlyBooks (requestsFromPerson db name)
So all you have to do is fill in the ???
for onlyBooks
and this should work! Hint: pattern matching is your friend.
Upvotes: 5