我正在处理此问题的一个版本:http://blog.gja.in/2014/01/functional-programming-101-with-haskell.html#.WIi0J7YrKHo
但是如果我要输入chop chop [1,0,0,0],它应该返回[0,3,0,0]。我尝试使用上面网站上给出的代码,但我似乎无法搞清楚。我也只是在3-4天前开始学习Haskell,所以我不确定正确的方向是什么。
提前谢谢!
答案 0 :(得分:1)
我认为你误解了预期的行为。猖獗指出,
chop [1,0,0,0]
会产生[0,0,0]
。我不明白,你在哪里得到[0,3,0,0]
,但我会向你介绍一下。
首先,chop
的定义,以及一些允许我引用定义的每个部分的注释。
chop [] = [] --chopNull
chop (1:xs) = xs --chopHead1
chop (n:xs) = (replicate (n - 1) (n - 1)) ++ xs --chopHeadN
你问过chop chop [1,0,0,0]
。这不是有效的代码。我假设你的意思是chop (chop [1,0,0,0])
。以此为出发点,我将进行一些等式推理。也就是说,我将通过替换定义的相关部分来转换有问题的程序片段。每行都有一条注释,指示当前行是如何从前一行计算的。
chop (chop [1,0,0,0])
= chop (chop (1:0:0:0:[]) --De-sugaring of List
= chop (chop (1:xs)) --Let xs = 0:0:0:[] = [0,0,0]
= chop (xs) --chopHead1
= chop (0:0:0:[]) --def of xs
= (replicate (0 - 1) (0 - 1)) ++ (0:0:[]) --chopHeadN
= [] ++ (0:0:[]) --From definition of replicate
= (0:0:[]) --From defintion of (++)
= [0,0] --re-sugaring
我上面做了一些松散的事情。值得注意的是,我在评论中将xs
等同于(0:0:0:[])
。这只是为了清楚定义中的模式匹配如何满足特定的替换。接下来,我使用chopHeadN
定义来匹配n=0
的情况,因为它是匹配的第一个东西。你必须相信我对复制和(++)的定义。
这就是那个特定的电话应该做的事情。但是,一般来说,如果您不知道特定函数的作用,最好从一些更简单的输入开始。对于列表,空列表[]
或单个列表,[n]
是很好的起点。然后转到两个元素列表。与此示例中一样,您可以删除部分定义并检查该部分对已知数据的作用。在ghci自己做。 (实际上,这就是我为复制(0-1)(0-1)表达所做的。我认为这将是一个错误。)