How to solve Haskell parse error on input 'otherwise'

606 Views Asked by At

I have a function which returns a list of halves of palindromes found from the input list. It works if I use an if-statement on one row but I'd like to use guards. Guards give me a parse error. I read many cases giving this kind of error, but I didn't figure out my case. Here is the code:

palindromeHalfs :: [String] -> [String]
palindromeHalfs xs = map firstHalf (filter palindrome xs)
    where
    firstHalf :: String -> String
    firstHalf ys | (length ys) `rem` 2 == 0 = take ((div (length ys 2)) ys
                 | otherwise                = take ((div (length ys 2) + 1) ys
    palindrome :: String -> Bool
    palindrome str | str == reverse str = True
                   | otherwise          = False 

And the error:

palindromeHalfs.hs:6:20: error: parse error on input `otherwise'
  |
6 |                  | otherwise                = take ((div (length ys 2) + 1) ys
  |                    ^^^^^^^^^

The function works if I replace

firstHalf ys | (length ys) `rem` 2 == 0 = take ((div (length ys 2)) ys
             | otherwise                = take ((div (length ys 2) + 1) ys

with

firstHalf ys = if (length (ys !! 0)) `rem` 2 == 0 then take ((div (length (ys !! 0)) 2)) ys 
                                                  else take ((div (length (ys !! 0)) 2) + 1) ys

In my code the if-statement is one row, it didn't fit here. I'd appreciate if someone can tell me which is preferred, if or guards. And of course, why my guards do not work.

1

There are 1 best solutions below

0
On BEST ANSWER

The parentheses are not balanced in

take ((div (length ys 2)) ys

As for style, guards are much preferred over if/else in cases where either may be used. Note also that even :: Integral a => a -> Bool is a function that exists; you don't have to invent it with rem.