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.
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
.