2011-07-06 51 views
0

我对Haskell相当陌生,并且试图自学Addison-Wesley的书中的语言 - 函数式编程工艺。数据库函数 - Haskell初学者需要帮助!

我卡上的运动之一,并想知道如果有人也许可以帮助:

我需要定义一个函数

borrowed :: Database -> Book -> Bool 

在图书馆数据库,可以检查是否一本书在数据库中已经借用,如果有,则返回True,否则返回False。这可能是一个非常简单的解决方案,但我似乎无法弄清楚!任何帮助将是巨大的

干杯

P

+0

你可以给我们一些关于'数据库'类型的信息吗? –

+0

嗨乔纳森,它是简单定义类型数据库= [(人,书)] – user832488

+0

谢谢!如果在我回家的时候没有人问过这个问题,我会回答它(现在就开始工作)。与Haskell一起玩吧! –

回答

2

你只是想看看书出现在列表中的任何地方。看看这个简单的方法是通过书籍列表上的归纳。当有一本书借出,你要比较的是,

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

然后,当你正在寻找通过多读书,要检查,如果你的关键是其中任何一个,

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

当你学会一些标准库函数,你可以清理,以类似,

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

+1用于在指向库函数之前显示幼稚的递归解决方案。 – Landei

1

我假设数据库是对的人,那人已签出一本书的名单。

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 

您是否明白这一切意味着什么,或者您希望我为您扩展它?

编辑:

  • 不再使用的<$>从Control.Applicative;换成fmap。他们的意思完全一样。
  • 从Control.Arrow中删除使用second;换成. snd。其实,我使用second是一个bug,现在已经修复了。
+0

嗨戴夫,谢谢你回答。无论如何你可以做到这一点,而不使用Applicative和Arrow的导入?它只是我还没有学到这一点,它扔我有点大声笑! – user832488

+0

此外,我已经定义了一个书的功能如下 - 是否有无论如何,你可以推荐类似于这是如何定义?书籍::数据库 - >人物 - > [图书] 书籍db searchPerson = [bookName | (personName,bookName)< - db,personName == searchPerson] – user832488

+0

@ user832488 1.看我的编辑。对不起,我不确定你想要我推荐什么。你对“书”的定义看起来很好。也许编辑你的问题来包含这个新标准? – dave4420

0

any函数定义只是为了这个目的!

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

当然,这种易于阅读的定义可以以任何方式进行修改。例如,有些人可能更喜欢这种形式:

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