user832488
user832488

Reputation: 1

Database Function - Haskell beginner needing help!

I'm fairly new to Haskell, and am trying to teach myself the language from the Addison-Wesley book - The Craft of Functional Programming.

I'm stuck on one of the exercises and wondered if someone might be able to help:

I need to define a function

borrowed :: Database -> Book -> Bool

over a library database that can check whether a book in the database has been borrowed and then return True if it has and False if it has not. It might be a really simple solution but I can't seem to figure it out! Any help would be great

Cheers

P

Upvotes: 0

Views: 410

Answers (3)

Daniel Wagner
Daniel Wagner

Reputation: 153152

The any function was defined just for this purpose!

borrowed db book = any (\(person, book') -> book' == book) db

Of course, this easy-to-read definition can be mangled in any number of ways. For example, some might prefer this form:

borrowed db book = any ((book==) . snd) db

Upvotes: 0

dave4420
dave4420

Reputation: 47062

I'm assuming the database is a list of pairs of a person and a book that person has checked out.

import Data.List (find)
import Data.Maybe (isJust)

whoBorrowed :: Database -> Book -> Maybe Person
whoBorrowed database book = fmap fst $ find ((== book) . snd) database

borrowed :: Database -> Book -> Bool
borrowed database book = isJust $ whoBorrowed database book

Do you understand what all that means, or would you like me to expand on it for you?

Edits:

  • Removed use of <$> from Control.Applicative; replaced with fmap. They mean exactly the same thing.
  • Removed use of second from Control.Arrow; replaced with . snd. Actually, my use of second was a bug, fixed now.

Upvotes: 1

gatoatigrado
gatoatigrado

Reputation: 16850

You just want to see if Book appears anywhere in the list. The simple way to look at this is via induction on the list of books. When there's one book loaned out, you want to compare that,

borrowed [(loan_to, loan_book)] key = loan_book == key

Then, when you're looking through more books, you want to check if your key is among any of them,

borrowed [] key = False
borrowed ((loan_to, loan_book):loans) key = key == loan_book || borrowed loans key

When you learn some standard library functions, you can clean it up to something like,

borrowed loans key = any ((==key) . snd) loans

Upvotes: 3

Related Questions