Haskell:写一个函数来复制`elem`

时间:2011-02-19 01:34:03

标签: haskell pattern-matching list-comprehension

对于我在哈斯克尔的第一次演讲,我们遇到了一系列问题。其中之一是当列表中存在n数时返回True,否则返回False。我设法得到了我认为在那里的中途,但我得到了不同的编译错误,我很沮丧,因为我甚至可以理解他们的意思。

到目前为止,我已经完成了以下

// No problem with this function
matches :: Int -> [Int] -> [Int]    // This function is to return the matches 
matches x y = [a | a <-y, a==x]     // ie. main> 1 [1,3,5,7,1,4] outputs [1,1]

// Here am stuck
myelem :: Int -> [Int] -> Bool
myelem x [] = False
myelem x (y:ys)
 | x == y = y : x myelem ys       // Am not sure about recursion as 
                                  // we have not yet covered

显然这是针对一个班级所以请不要发布答案。但也许一些例子可以帮助我推断Haskell的工作方式以及如何解决问题。任何指针都将受到大力赞赏。


matches :: Int -> [Int] -> [Int]
matches x y = [a | a <-y, a==x]

myelem :: Int -> [Int] -> Bool
myelem x [] = False
myelem x (y:ys)
 | x == y = True
 | otherwise = myelem x (ys)

干杯球员

5 个答案:

答案 0 :(得分:2)

问题在于你的最后一个等式:

myelem x (y:ys)
 | x == y = y : x myelem ys

这里有两个问题:

  1. 如果您想将myelem用作中缀运算符,则必须将其包围在反引号中,如下所示:

    x `myelem` ys
    
  2. 鉴于这就是你的意思,你方程式的右手边没有打字;列表构造函数(:)要求其第二个参数是列表,而不是Bool。此外,(:)构建了一个列表,myelem应该返回Bool

  3. 想想你想要做什么。如果x == y,您只想返回True,对吧?并且otherwise,您想要返回检查列表其余部分(ys)的结果。希望有所帮助。

答案 1 :(得分:1)

你实际上非常接近正确的答案。不过,我看到了两个主要问题。一个是在最后一行代码上调用myelem需要在它周围加上反引号以使其成为中缀(x `myelem` ys)或没有反引号的前缀调用(myelem x ys)。此外,您不希望将y添加到递归调用的结果中。实际上你不需要第二种模式的条件:只需考虑myelem x (y:ys)应该使用简单的布尔运算返回的内容以及你已经在那里进行的递归调用。

答案 2 :(得分:1)

您尝试在最后一行连结IntBool;再想一想。

您永远不会从True返回myelem;有时它是合适的。

修复这些问题后,代码就可以运行。

答案 3 :(得分:1)

你也可以使用以下功能的某种组合来编写你的函数(使用下面的函数至少有两种方法):

filter :: (a -> Bool) -> [a] -> [a]

从列表中删除元素,除非它们满足某些条件

null :: [a] -> Bool

返回列表是否为空

not :: Bool -> Bool

是逻辑否定

or :: [Bool] -> Bool
如果Bool列表包含一个或多个True值,则

返回True。

显然,你已经解决了问题,但它可能会帮助你探索做同样事情的其他方法。

答案 4 :(得分:0)

请注意,您还可以根据myelem定义matches函数。

  • 如果项目不在列表中,匹配的内容会返回什么?
  • 如果项目在列表中一次会匹配什么?两次?很多次?
  • 你是否关心第二种情况下的整个回报值? (提示:否)