我从一本书中练习,我必须为图书馆拿一个数据库,我必须通过检查一个充满表格元组的数据库来查明当前是否正在借书。 / p>
type Person = String
type Book = String
type Database = [(Person,Book)]
我必须使用的功能是
borrowed :: Database -> Book -> Bool
当数据库中充满了当前正在借阅的所有书籍时,本书就是我正在搜索的书籍,如果书籍被借用,它应该返回True
这是我到目前为止所得到的,ghci一直告诉我在getTuple函数中匹配类型时遇到问题,但我无法弄清楚出了什么问题
-- Database I will use for the function
exampleBase :: Database
exampleBase =
[ ("Alice","Tintin") , ("Anna","Little Woman") ,
("Alice","Asterix") , ("Rory","Tintin") ]
borrowed :: Database -> Book -> Bool
borrowed dBase book
| getTuple dBase book == book = True
| otherwise = False
getTuple :: Database -> Book -> Book
getTuple (x:xs) bk
| x == null = "notBook"
| (getBook x) == bk = bk
| (getBook x) /= bk = getTuple xs bk
getBook :: (String,String) -> Book -> Book
getBook (first,second) bk
| second == bk = bk
| otherwise = "notBook"
答案 0 :(得分:2)
首先,x == null
无效。
在Haskell中,null
是函数。它需要列表并告诉您列表是否为空。所以null x
可能会做点什么。除了x
这里不是列表,它是元组。
也许你的意思更像是
getTuple [] bk = "notBook"
getTuple (x:xs) bk
| (getBook x) == bk = ...
| (getBook x) /= bk = ...
不确定为什么要测试该条件两次,一次使用==
,一次使用/=
;你可以简单地用otherwise
替换第二个。
就此而言,不确定为什么需要单独的getBook
功能;你可以简单地做
getTuple [] bk = "notBook"
getTuple ((person, book) : xs) bk = if book == bk ...
然后,我甚至不确定为什么getTuple
会返回Book
(如果找不到,则会返回魔术字符串"notBook"
),borrowed
必须比较...当您可以从此处返回True
或False
时。
borrowed [] bk = False
borrowed ((person, book) : xs) bk = if book == bk then True else borrowed xs bk
答案 1 :(得分:2)
这与解决方案非常接近,但我们可以解决代码中的一些问题:
在Haskell中,我们倾向于尽可能避免无穷无尽的模式匹配,因为这样的代码可能会在运行时崩溃。例如,给定空列表,getTuple函数将崩溃。在使用-Wall
进行编译时,编译器会提醒您这种情况Haskell提供数据类型来帮助您表示不变性。例如,如果要表示0或1值,请使用Maybe。例如:" notBook"是一本书的有效名称,所以如果你找不到你想要的价值,你可以使用Nothing,如果你没有,你可以使用Just bk。
在你的getTuple函数中你尝试将x与null进行比较,在Haskell中为null是一个检查列表是否为空的函数,因此你在那里有一个tyoe不匹配。
getTuple可能不是您的功能的绝佳名称:)我确定您可以提供更具信息性的名称。
希望这有帮助。
答案 2 :(得分:1)
好吧,这可以解决您的类型错误:
getTuple (x:xs) bk
| null xs = "notBook"
| (getBook x) bk == bk = bk
| (getBook x) bk /= bk = getTuple xs bk
但我想告诉你,为特殊情况返回一个特殊值("notBook"
)不是一个好的风格。如果您找到了本书,或者尝试下一本书,或者最后返回True
,您可以简化解决方案,只返回False
。
答案 3 :(得分:1)
null
是一个函数,而不是一个值。
你不能这样做
x == null
但你可以这样做
null x
除外x
也不是列表!
我认为您打算检查列表是否为空,这可能不是使用模式匹配
getTuple [] _ = ....
这将在你已经拥有的线之前。