Haskell:具有多态相等函数的递归

Mat*_*att 2 polymorphism haskell

好的,我们还没有学过多态函数,但我们仍然需要编写这段代码.

Given:
nameEQ (a,_) (b,_) = a == b
numberEQ (_,a) (_,b) = a == b
intEQ a b = a == b
member :: (a -> a -> Bool) -> a -> [a] -> Bool
Run Code Online (Sandbox Code Playgroud)

我补充说:

member eq x ys | length ys < 1 = False
               | head(ys) == x = True
            | otherwise = member(x,tail(ys))
Run Code Online (Sandbox Code Playgroud)

但我得到的错误是不正确的类型以及其他一些东西.我们必须查看某个类型中是否存在元素.所以我们有以上两种类型.给出的一些例子:

phoneDB = [("Jenny","867-5309"), ("Alice","555-1212"), ("Bob","621-6613")]

> member nameEQ ("Alice","") phoneDB
True
> member nameEQ ("Jenny","") phoneDB
True
> member nameEQ ("Erica","") phoneDB
False
> member numberEQ ("","867-5309") phoneDB
True
> member numberEQ ("","111-2222") phoneDB
False
> member intEQ 4 [1,2,3,4]
True
> member intEQ 4 [1,2,3,5]
False 
Run Code Online (Sandbox Code Playgroud)

不完全确定我需要在这做什么.任何关于此的帮助或文档都会很棒.谢谢!

Nei*_*own 7

各种各样的事情(我不会写出完整的答案,因为这是家庭作业):

  1. length ys < 1 可以更简单地表达为 null ys
  2. 你不需要在函数参数周围使用括号. head(ys)更常见的是写作head ys
  3. 如果需要,您可以将顶壳和其他两个转换为模式匹配而不是防护. member eq x [] = ...将匹配空案例,member eq x (y:ys) = ...将匹配非空案例.
  4. 你是==用来比较的.但是你的意思是使用eq你给出的功能.
  5. 您将参数包含在成员中,就好像这是Java或类似的一样.在Haskell中,参数由空格分隔,所以member(x,(tail(ys))应该是member x (tail ys).

  • 对于第2点:不仅那些不必要的parens,他们实际上会欺骗你相信那些东西被分组的方式不是; 例如,`foo ab(c)`用三个参数调用`foo`,而不是两个.你可能的意思是`foo a(bc)` (2认同)

Dan*_*tin 5

你忽略的那些错误"关于不是正确的类型以及其他一些东西"很重要.他们告诉你什么是错的.

例如,我第一次把你的代码扔进去ghc了:

Couldn't match expected type `a -> a -> Bool'
       against inferred type `(a1, [a1])'
In the first argument of `member', namely `(x, tail (ys))'
In the expression: member (x, tail (ys))
In the definition of `member':
    member eq x ys
             | length ys < 1 = False
             | head (ys) == x = True
             | otherwise = member (x, tail (ys))
Run Code Online (Sandbox Code Playgroud)

好吧,当我看到它很简单时 - 你输入了

member(x,tail(ys))
Run Code Online (Sandbox Code Playgroud)

当你明确表示:

member x (tail ys)
Run Code Online (Sandbox Code Playgroud)

逗号意味着Haskell中你不想要的东西.

一旦我做出了改变,它再次抱怨说你已经停止了eq争论member.

如果你还没有学习Haskell类型类,那么之后的错误就更难了,但是说它需要使用传入的eq函数进行比较就足够了==.