List 序曲!!:索引太大(基于对以前计算的列表元素的访问的Haskell递归。)

List 序曲!!:索引太大(基于对以前计算的列表元素的访问的Haskell递归。),list,haskell,recursion,List,Haskell,Recursion,我在Haskell有这样的代码。它在递归地填充列表。一些“i”参数(除0外,每个偶数)是根据以前的计算结果计算的 fillIn :: Int -> Int -> [Int] -> [Int] fillIn max_val i list | i > max_val = list | i == 0 = ((function i):[]) ++ (fillIn max_val (i+1) list) | even i = (((list!!(i `div` 2))

我在Haskell有这样的代码。它在递归地填充列表。一些“i”参数(除0外,每个偶数)是根据以前的计算结果计算的

fillIn :: Int -> Int -> [Int] -> [Int]
fillIn max_val i list
  | i > max_val = list
  | i == 0 = ((function i):[]) ++ (fillIn max_val (i+1) list)
  | even i = (((list!!(i `div` 2)) + (i `div` 2)):[]) ++ (fillIn max_val (i+1) list)
  | otherwise = ((function i):[]) ++ (fillIn max_val (i+1) list)
它生成错误:前奏曲。!!:索引太大当它试图访问位于1的列表时(列表!!1)。我不知道为什么,因为当它计算
fillIn max_val 2 list
时,它已经
fillIn max_val 1 list
完成了。 你知道我怎么修吗?
提前感谢您。

我冒昧地以一种更“传统”的方式重新编写了您的代码,(希望)没有 改变它的意思

fillIn :: Int -> Int -> [Int] -> [Int]
fillIn max_val i list
    | i > max_val = list
    | i == 0 || odd i = f i: fillIn max_val (i + 1) list
    | even i = list !! (i `div` 2) + (i `div` 2): fillIn max_val (i + 1) list
看起来你还是在数组上使用了命令式算法,并将其压缩到Haskell中 很难理解代码应该做什么。但我猜了很久 您可能希望
list
成为一个“累加器”,函数是尾部递归的。 然后我可以这样重写:

fillIn :: Int -> Int -> [Int] -> [Int]
fillIn max_val i list
    | i > max_val = list
    | i == 0 || odd i = fillIn max_val (i + 1) (f i                              : list)
    | even i          = fillIn max_val (i + 1) (list !! (i `div` 2) + (i `div` 2): list)
-它确实会起作用

我仍然不确定它计算了什么。某种递归序列。如果你告诉我你的
目标是,也许我们可以设计一个更“惯用”的版本。

你检查
i>max_val
,但你永远不会检查
列表是否确实足够长,可以让你尝试的每个索引工作。
(x:[])+…
写得更简单。
x:
,我会用类似于
fillIn max_val list=map f(take max_val list)++drop max_val list,其中f=…
的东西来定义它。当询问您编写的非工作代码时,您应该始终解释代码应该做什么。当我们不知道你们在期待什么的时候,真的很难说如何解决这个问题。各位,这是一个好问题,马上收回你们的投票!