好,你的体面的开始,但重要的是要注意,你没有采取最“Haskell”的方法。
让我告诉你一些不同的方法解决这个问题:
方法1:递归函数
首先,我们可以写一个递归函数(如你)来解决这个。
要做到这一点,我们首先容纳用于一个基本情况(一个不会,一般情况下,允许一个无限循环)。这应该工作:
remove [] _ = []
这仅仅是说,如果我们从一个空的列表中删除元素,我们结束了一个空列表。就这么简单。 _
意味着我们不在乎x
是什么值。现在
我们必须定义其他案件。对于这一点,我会用后卫(我敢肯定有其他的办法,基本情况还增加了完成):
remove [] _ = []
remove (x:xs) y
| x > y = remove xs y
| otherwise = x : remove xs y
所以,第一行(remove (x:xs) y
)是说,我们的函数将采取列表(其中x
是磁头/第一值和xs
是其余部分)。
第二行是说,如果x
大于y
,请考虑其余元素,并且我们不认为x
是我们最终解决方案的一部分。
第三行(otherwise
捕获所有的情况下,如果命中,就像if/elseif/else
在if/elseif/else
其他语言的条件块中的else
)。如果我们到了这一点,我们知道这是不正确的x > y
所以我们认为我们的价值观(xs
)的其余部分,我们包括x
,但我们与x
做了现在。
现在,这种方法工作体面,但有一个简单的办法:
方法2:列表综合
使用list comprehensions我们可以建立一个非常简单的,功能强大的解决方案:
remove xs y = [x | x <- xs, not (x > y)]
如果你曾经学过set-theory(特别是set-builder notation),你应该看起来很奇怪。我们来看看每个部分的含义。
[...]
- 东西方括号只是意味着我们正在建设一个列表
x |...
- 意味着我们的列表将包含x
S,从而使(该|
手段 “使得”)...
x <- xs,
- x
是xs
(逗号表示 “和”)的元素,...
not (y > x)
- 这是不正确的y
大于x
正如你所看到的,第二种方法几乎完全模仿你的问题的描述。这确实是Haskell的力量,单词和抽象几乎都直接映射到Haskell代码中。
方法3:使用filter
由于下面的评论的状态的第三替代方案将是把它定义为这样:
remove y = filter (<=y)
当过滤器将只保留是小于或等于的元素到y。 (感谢Daniel Wagner提供这种方法)。
你得到了无限循环,因为'然后删除(drop 0 l1)x'你在同一个列表上重复出现,'drop'的第一个参数表示要删除多少个元素,并且您错误地输入了'drop 0'而不是你需要“降1”。 – 2013-04-10 10:20:17