【问题标题】:Haskell recursion with list of characters带有字符列表的 Haskell 递归
【发布时间】:2015-07-31 16:53:21
【问题描述】:

我正在研究 Haskell 并且出现了一些问题,我被困了几天......所以我基本上试图通过字符列表(字符串)进行递归,一旦它到达字符串的末尾,有没有办法让我再次从头开始递归列表吗?

这是用于递归遍历字符串一次的代码。

repeat2' :: [Char] -> Int -> [Char]
repeat2' [] _ = undefined
repeat2' (x:xs) 1 = [x]
repeat2' (x:xs) k
    | (k > 0) = x: repeat2' xs(k-1)

它适用于

repeat2' "嘿" 1 = "h"

repeat2' "嘿" 2 = "他"

repeat2' “嘿” 3 = “嘿”

但是一旦我尝试了

repeat2' "hey" 4 = "hey*** 例外:Prelude.undefined"

因为它会“repeat2' [] _ = undefined”;

但我希望它打印出来

repeat2' “嘿” 4 = “嘿”

..那么我该如何回到字符串的头部呢?

感谢您的帮助!

【问题讨论】:

  • 这是给你的家庭作业,我说得对吗?因为看起来你的两个同学在过去几天里要求的几乎一样;)(他们两个刚刚在这里注册)
  • 顺便说一句:它将是undefined for 4,因为您在第一个案例中告诉您的功能是这样的 - 我也给您与您的同学相同的提示:而不是删除 @987654323 @你可能想把它放在另一个地方,进一步调用repeat2'可能会再次找到它......进一步提示:你可以使用x : ...x添加到列表中......也许你知道可以附加它的东西相反...
  • 是的,哈哈,只是我没有要求答案;只是想法和建议;我也不太明白你所说的“把它放在某个地方以供进一步调用”..我对这种语言很陌生,不知道你会怎么做..我不确定如何传递字符串以从头开始!
  • 好吧,至少其中一个从一开始就说了这么多(你看:通常我们处理家庭作业的问题有点不同——就像 Luqui 所做的那样)——对于你的问题,我给了你另一个提示(但你应该再读一次):你的问题与"hey" 4 开始时有"" 1 离开 - 如果它在"h" 1" 甚至"hey" 1 的位置不是很好吗? (另请参阅 luqui 的提示)- 如果您在第二次递归调用中以 "eyh" 3 结束,则不考虑性能,您可以得到这个 - 现在您如何从列表的开头到结尾获得 h

标签: string list haskell recursion character


【解决方案1】:

让我标记方程式以便稍后引用它们。

   repeat2' :: [Char] -> Int -> [Char]
1) repeat2' [] _ = undefined
2) repeat2' (x:xs) 1 = [x]
   repeat2' (x:xs) k
3)     | (k > 0) = x: repeat2' xs(k-1)

让我们追踪repeat2' "hey" 4 的减少。首先我会将字符串脱糖成一个列表

repeat2' ['h', 'e', 'y'] 4

然后将列表放入其缺点单元格

repeat2' ('h':'e':'y':[]) 4

现在我们可以开始了

repeat2' ('h':'e':'y':[]) 4
-- equation 3 applies, x = 'h', xs = 'e':'y':[], k = 4
'h' : repeat2' ('e':'y':[]) 3
-- the first element of the result is known now, so it is printed by the repl
-- equation 3 applies ot the remainder
'h' : 'e' : repeat2' ('y':[]) 2
-- e is now known and printed
-- equation 3 applies
'h' : 'e' : 'y' : repeat2' [] 1 
-- y is known and printed
-- equation 1 applies
'h' : 'e' : 'y' : undefined
-- the repl errors out because of undefined

从而解释输出

"hey***Exception: Prelude.undefined

希望这能帮助你理解。

一个问题是,为了循环列表,您需要保留它以进行递归调用。请注意,当我们打印 h、e、y 时,接下来要使用的信息不再存在。除了您正在遍历的列表之外,您还需要原封不动地传递列表。

【讨论】:

  • 哦,好吧,我明白了;但是,是的,我坚持再次传递字符串以通过列表...我试图做“(k / = 0)= x:repeat2'x:xs(k-1)”如果有一个带有“k”的空列表还有更多字符要通过,再次传递字符串以再次从头部开始,但它仍然不起作用..我只是想不出其他方法..还有更多提示吗?
  • 最简单的方法是你可以再次传递字符串(或记住它),如果你通过一个额外的参数来扩展你的函数,比如:repeat list (x:xs) k = ...,然后用repeat "hey" "hey" 4开始你的
猜你喜欢
  • 1970-01-01
  • 2018-07-20
  • 2016-08-03
  • 2019-07-21
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 2013-01-17
相关资源
最近更新 更多