如何使列表理解返回并在Haskell中进一步使用它

时间:2014-09-25 00:03:18

标签: haskell

我正在尝试编写一个函数"借用",如果它在借阅者到书籍的数据库中找到输入的书名,则必须返回true。如果在数据库中找不到这样的书,则表示该书从未被借用过,因此该函数必须返回false。到目前为止,我已经尝试了一千种不同的方法来做到这一点,而且我总是只是实现它的一步。这是我的代码:我不知道如何获取列表(空或单个字符串)并使用它来与bookTitle进行比较,如果它们相同则返回true,否则返回false。

type Person = String
type Book = String
type Database = [(Person, Book)]

database::Database
database = [
    ("1", "Haskell"),
    ("2", "Prolog"),
    ("2", "O/S Principles")]

borrowed::Database->Book->Bool
borrowed db bookTitle =
    [loanedBook | (person, loanedBook)<-db, bookTitle == loanedBook]
    --I want to write something like:
    --if above comprehension comes up with a string for loanedBook, then True else False


main = do
print(borrowed database "Haskell")

1 个答案:

答案 0 :(得分:3)

你快到了。如果没有书籍匹配,您的列表理解将为空。好吧,你可以手动测试:

borrowed db bookTitle
   = case [loanedBook | (person, loanedBook)<-db, bookTitle == loanedBook]
       of [] -> False -- Comprehension is empty
          _  -> True  -- Anything but an empty list means, there was a match!

同样,您可以使用null功能进行该检查。

然而,构建这种理解并不是必需的:基本上,你要做的就是检查谓词(即“第二元组元素等于bookTitle”)列表的所有元素,并报告任何元素是否属实。惊喜:有一个标准的Haskell函数就是这样,称为any

borrowed db bookTitle = any (\(_, loanedBook) -> loanedBook == bookTitle) db

或者,您可以先将列表简化为loanedBook个标题,然后使用更简单的elem函数:

borrowed db bookTitle = bookTitle `elem` map snd db