Amir Nabaei
Amir Nabaei

Reputation: 1642

Haskell Error in List

I dont know what is wrong with my code, I just want to get a list and fill it up properly and return that list as a result of that function. could you help me to solve this problem?

 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) 

I want to fill the zeros with non repeated numbers

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

Upvotes: 0

Views: 124

Answers (2)

viorior
viorior

Reputation: 1803

We could a bit modify original version:

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

and use:

fillZero = flip fillZero' [1..]

> fillZero [0,305,0,0,0,8,0,0]
[1,305,2,3,4,8,5,6]

Upvotes: 1

Ming-Tang
Ming-Tang

Reputation: 17651

You are writing Haskell as if it's an imperative language. The second expression in the do block, new:xs, does nothing at all.

The do block after then

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

Because dos and lets actually translate to lambdas:

let x = a
b x

becomes

(\x -> b x)(a)

, your do block translates to:

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

and new:xs is discarded in the middle.

Do notation is only useful if you are dealing with monads. Otherwise, it leads to misleading code.

See also:

Upvotes: 2

Related Questions