2011-02-19 57 views
3

对于我在哈斯克尔的第一次演讲,我们给出了一系列问题。其中之一是在列表中存在n个数字时返回True,否则返回False。我设法得到了我认为在那里的一半,但是得到了不同的编译错误,并且非常沮丧,因为我甚至可以理解它们的意思。Haskell:写一个函数来复制``ellem'

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

// 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的运作以及如何解决这个问题。任何指针都将被大量赞赏。


SOLUTION

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) 

干杯家伙

+0

@pelotom,@Jeremiah Willcock,@ 9000:非常感谢这么多人,我只是觉得把我的推理从强制性转变为陈述性是非常具有挑战性的。只是为了澄清;当`myelem x(ys)`被执行时,它实际上是否从列表中删除了元素直到为空,还是仅仅评估列表上剩余的元素,直到没有剩下的元素为止? – Carlos 2011-02-19 03:13:17

回答

2

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

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

有两个问题在这里:

  1. 如果你想使用myelem作为中缀运算符,你必须围绕着它的反引号,像这样:

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

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

1

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

1

您尝试连接最后一行中的IntBool;再想一想。

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

一旦这些问题得到解决,代码就可以工作。

0

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

  • 如果项目不在列表中,将返回什么?
  • 如果项目在列表中一次会返回什么?两次?多次?
  • 你关心第二种情况下的整个回报价值吗? (提示:无)
1

您还可以使用以下功能的一些组合写你的函数(有使用下面的功能做的至少两种方式):

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

从删除元素列表,除非它们满足一些准则集列表

null :: [a] -> Bool 

回报是否为空或不

not :: Bool -> Bool 

是逻辑否定

or :: [Bool] -> Bool 

返回true布尔列表包含一个或多个真实值。

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