您好我是初学者,我尝试在Haskell中学习递归 但我的递归功能不会给我一个解决方案,我的电脑冻结。这是我的功能。我希望我的函数得到一个数字,然后用1减去它。 每次减去数字时,它都会被添加到以0开头的列表中。例如 我们3 = [0,3,2,1]
we w
|w == 0 = []
|w >0 = te [0] w w
|w <0 = error "test"
|otherwise = error "test"
where
te (x:xs) f c = te (x:f:xs) (f-1) (c-1)
te (x:xs) f 0 = x:xs
te (x:xs) 0 c = x:xs
te (x:xs) 0 0 = x:xs
答案 0 :(得分:4)
您的功能存在一些问题,但目前只是程序冻结的原因:
te (x:xs) f c = ...
是一种匹配几乎所有可能性的模式:第一个参数为非空列表的所有调用都将匹配,其余子句将永远不会“触发”,因为这些是第一个子句的子集模式;和你的功能也有一些奇怪的东西(没错,但效率不高或优雅):
f
函数中使用c
和te
,但这些值始终具有相同的值;和w > 0
,w < 0
和w == 0
进行比较,否则,这很奇怪,因为价值不可能大于,不小于和不小于在同一时间平等。所以也许我们应该先回到绘图板。第一步或多或少是一个好的:我们定义函数we
,我们区分三种情况:
we w | w > 0 = ...
| w == 0 = ...
| otherwise = ...
显然(这不在您发布的规范中),我们应该在w < 0
上出错,并在w
等于零的情况下返回一个空列表,所以:
we w | w > 0 = ...
| w == 0 = []
| otherwise = error "w is less than zero"
现在w > 0
我们知道我们会生成一个以0
开头的列表,后跟别的东西,所以我们可以写:
we w | w > 0 = 0 : ...
| w == 0 = []
| otherwise = error "w is less than zero"
因此我们构建了一个列表(_:_)
,其中0
为头。现在剩下的就是调用递归函数(例如te
):
we w | w > 0 = 0 : te w
| w == 0 = []
| otherwise = error "w is less than zero"
where te n = ...
现在te
有两种可能性:n > 0
,在这种情况下,我们“ emit ”n
,并对n
的递减执行递归1}};或者在n <= 0
的情况下,我们终止(所以我们生成一个空列表):
we w | w > 0 = 0 : te w
| w == 0 = []
| otherwise = error "w is less than zero"
where te n | n > 0 = n : te (n-1)
| otherwise = []
就是这样!