来自元组列表的特定信息

时间:2016-05-09 16:34:24

标签: haskell

我从一本书中练习,我必须为图书馆拿一个数据库,我必须通过检查一个充满表格元组的数据库来查明当前是否正在借书。 / 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"

4 个答案:

答案 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必须比较...当您可以从此处返回TrueFalse时。

borrowed [] bk = False
borrowed ((person, book) : xs) bk = if book == bk then True else borrowed xs bk

答案 1 :(得分:2)

这与解决方案非常接近,但我们可以解决代码中的一些问题:

  1. 避免详尽的模式匹配
  2. 在Haskell中,我们倾向于尽可能避免无穷无尽的模式匹配,因为这样的代码可能会在运行时崩溃。例如,给定空列表,getTuple函数将崩溃。在使用-Wall

    进行编译时,编译器会提醒您这种情况
    1. 在您的类型中编码不变性
    2. Haskell提供数据类型来帮助您表示不变性。例如,如果要表示0或1值,请使用Maybe。例如:" notBook"是一本书的有效名称,所以如果你找不到你想要的价值,你可以使用Nothing,如果你没有,你可以使用Just bk。

      1. 注意类型不匹配
      2. 在你的getTuple函数中你尝试将x与null进行比较,在Haskell中为null是一个检查列表是否为空的函数,因此你在那里有一个tyoe不匹配。

        1. 很好地命名
        2. 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 [] _ = ....

这将在你已经拥有的线之前。