2

I got a question regarding Haskell, I tried to make a function to half an even number only in a list and return the final list with only the even number(s) got modified(got halved) with the rest of the element remained untouched.

But when I try to compile my code, I gave an error saying that "error: parse error on input ‘if'" and I couldn't find the solution for it.

halfEvens :: [ Int ] -> [ Int ]
halfEvens xs = [x|x<-xs]
                if x mod 2 == 0
                the x = x / 2
                else
                x = x
1
  • Sorry because my code is a bit messed up. So what should I do in order to make my function work as what I want ? Do you have any recommendation ? Commented Nov 19, 2017 at 18:15

3 Answers 3

4

Your code has multiple issues:

  • [x|x<-xs] doesn't do anything useful. This will just evaluate to xs.
  • If you're using mod as an infix operator, it needs backticks around it
  • You can't reassign variables. then x = x / 2 and x = x are illegal in Haskell.

The main problem though is the fact that you have an empty list comprehension ([x|x<-xs]), with an if expression just kind of floating underneath it. I believe your intent was to put the if inside of the comprehension. Something like:

halfEvens :: [Int] -> [Int]
halfEvens xs = [if x `mod` 2 == 0 then x `quot` 2 else x | x <- xs]

Changes:


main = do
  putStrLn . show $ halfEvens [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

[1,1,3,2,5,3,7,4,9,0]

Your code shows some serious misunderstandings of Haskell though. I recommend sitting down with a good book and trying out all the examples. Haskell is not an easy language. Don't try to rush through it.

Sign up to request clarification or add additional context in comments.

Comments

3

So, you want to apply a function that halves even numbers, but leaves odd numbers alone. We can write a function to perform this transform on a single Int, using even from the prelude:

halfEven :: Int -> Int
halfEven x | even x = x `div` 2
           | otherwise = x

Now we can map this function over a list of Int:

halfEvens :: [Int] -> [Int]
halfEvens xs = map halfEven xs

Or go point free:

halfEvens = map halfEven

Or use a list comprehension:

halfEvens xs = [halfEven x | x <- xs]

2 Comments

What did the map do ? Is it importing the 'halfEven' back to the 'halfEvens' ? Or in other word assigning the value of 'halfEven' to the 'halfEvens' ?
@Wandy map halfEven == \xs -> [halfEven x | x <- xs].
2

Keeping as much of your original code/intent as possible,

halfEvens xs = [x | x <- xs, x <- [   -- instead of x = ...
                 if x `mod` 2 == 0
                   then {- x = -} x `div` 2
                   else {- x = -} x ]]

Its type gets deduced as halfEvens :: Integral t => [t] -> [t].

Funny thing about it is that we're allowed to use the same variable name there, with the x <- [...] construct; it just gets shadowed. But it's OK, since we're only interested in the new value anyway. That way we treat it mentally as a variable "update", although there's no updating variables in Haskell, of course.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.