Amir Nabaei
Amir Nabaei

Reputation: 1642

More than one functions after if then .., don't work in Haskell

I have a basic problem, after if .. then I can not have more than one function, why?

check [] _ _ = []
check (x:xs) limit counter = if (x> head xs && counter < limit)
                              then incr counter -- I want here add another action 
                              else if ( x < head xs )
                                   then check xs limit counter
                                   else  incr x

main = do 
  print $ check [4,3,5,6] 1 0
  --- The answer I aim is : [3,4,5,6]

The goal of the check is to find whether each element is bigger than the next one or not, if yes then increase counter and do another action like swap their places, and there is a limit for this action, like here is just 1 time, means just 1 times it can do that action not more.

Upvotes: 1

Views: 248

Answers (2)

Alexander Vieth
Alexander Vieth

Reputation: 876

Regarding your second implementation of check:

check ( modXs, []) _ _  = modXs
check ( modXs, [x]) _ _ = x : modXs
check ( modXs, (x1:x2:xs)) counter limit 
    | x1 > x2 && counter > limit =  x2:check (x1 : xs)  (incr counter) limit
    | otherwise = x1 : check (x2 : xs) counter limit 

You're nearly there, but it's ill typed because the first argument to check is a pair, while in the recursive definition you provide a list.

Upvotes: 1

wit
wit

Reputation: 1622

You could use guards instead:

check [] _ _ = []
check (x:xs) limit counter
             | x> head xs && counter < limit = incr counter
             | x < head xs                   = check xs limit counter
             | otherwise                     = incr x

You could also use case and MultyIf extension

Instead action from incr counter you could write check xs limit (counter + 1)

About exchanging, you could try

 ...  
| x> head xs && counter < limit = check (head xs : x : tail xs) limit (counter + 1)

I see, you also need special case for head [] = error, so you should divide you function to check (x:y:xs) .. and check [x].

So, for check (x:y:xs) .. case we can rewrite

 ...  
| x> y && counter < limit = check (y : x : xs) limit (counter + 1)

When you do this, you already find that we have empty list as result. But you want to save modified list

So, try to add change check function

check' xs = reverse . check ([], xs) 0

check ( modXs, []) _ _  = modXs
check ( modXs, [x]) _ _ = x : modXs
check ( modXs, (x:y:xs)) counter limit = ...

Main point Inside the function there aren't "static local variables", but in most cases recursion is welcome. If it is really need to use "static local variables", you could use "data in contents": monads, like IO, IORef of pure, like State

Upvotes: 3

Related Questions