0

我不知道我的代码有什么问题,我只想获取一个列表并正确填写并返回该列表作为该函数的结果。你能帮我解决这个问题吗?

 fill  [] counter= []
 fill  (x:xs) counter= do
                   (if x==0  
                   then do
                       let new =counter+1
                       new:xs
                       fill xs new
                   else 
                       fill xs counter) 

我想用不重复的数字填充零

  main = do 
 fill [9,0,9,0,0,0] 0   -- expexted to get [9,1,9,2,3,4]
4

2 回答 2

2

您正在编写 Haskell,就好像它是一种命令式语言。do块中的第二个表达式new:xs, 根本不做任何事情。

之后的do块then

do
  let new =counter+1
  new:xs
  fill xs new

因为dos 和lets 实际上转换为 lambda:

let x = a
b x

变成

(\x -> b x)(a)

,您的do块转换为:

(\new -> (\discarded -> fill xs new)(new:xs) ) (counter + 1)

new:xs在中间被丢弃。

Do 表示法仅在处理 monad 时才有用。否则,它会导致误导性代码。

也可以看看:

于 2013-10-10T03:09:41.000 回答
1

我们可以稍微修改原始版本:

fillZero' (z:zs) y'@(y:ys) = 
         if z == 0 
         then y : fillZero' zs ys
         else z : fillZero' zs y'
fillZero' _ _ = []

并使用:

fillZero = flip fillZero' [1..]

> fillZero [0,305,0,0,0,8,0,0]
[1,305,2,3,4,8,5,6]
于 2013-10-10T10:13:28.073 回答