在Haskell切碎Hydra

时间:2017-01-25 14:23:29

标签: haskell recursion

我正在处理此问题的一个版本: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,所以我不确定正确的方向是什么。

提前谢谢!

1 个答案:

答案 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)表达所做的。我认为这将是一个错误。)