Fernando Rodriguez wrote:

Hi,

I'm trying to write a function that finds out the week day using the Zeller congruence (http://en.wikipedia.org/wiki/Zeller's_congruence).

However, ghc complains about: parse error on input `=' at the "if m <= 2 then " line. I believe this is some sort of layout error. Can someone point out what I am doing wrong?

Here's the code:

data DiaSemana = Lunes | Martes | Miercoles | Jueves | Viernes
                | Sabado | Domingo deriving (Show, Eq, Ord, Enum)
diaDeSemana d m a = toEnum num :: DiaSemana
                    where
                        num = zeller x y z
                        zeller x y z = (700 + (26 * x - 2) `div` 10
                             + d + y + y `div` 4 + z `div` 4 - 2 * z)
                             `mod` 7
if m <= 2 then x = m + 10
                            y = (a - 1) `mod` 100
                            z = (a-1) 'div' 100
                        else                             x = m - 2
                            y = a  `mod` 100
                            z = a `div` 100


That looks like it's been mangled a bit by your mail program or mine, but anyway:

This is not a layout problem. The problem here is simply that you can't put "ifs" around chunks of definitions. "if" is an expression level concept, not a definition-level one.

You could try:

diaDeSemana d m a = toEnum num :: DiaSemana
                    where
                        num = zeller x y z
                        zeller x y z = (700 + (26 * x - 2) `div` 10
                             + d + y + y `div` 4 + z `div` 4 - 2 * z)
                             `mod` 7
                        x | m <= 2    = m + 10
                          | otherwise = m - 2
                        y | m <= 2    = (a - 1) `mod` 100
                          | otherwise = a  `mod` 100
                        z | m <= 2    = (a-1) 'div' 100
                          | otherwise = a `div` 100


or, to avoid the ugly duplication of the m <= 2 constraint, we can use an if in an expresson like this:

diaDeSemana d m a = toEnum num :: DiaSemana
                    where
                        num = zeller x y z
                        zeller x y z = (700 + (26 * x - 2) `div` 10
                             + d + y + y `div` 4 + z `div` 4 - 2 * z)
                             `mod` 7
                        (x,y,z) = if m <=2 then
                                     (m+10,(a-1)`mod`100,(a-1)`div`100)
                                  else
                                     (m-2,a`mod`100,a`div`100)


... or, replacing the if with guards again ...

diaDeSemana d m a = toEnum num :: DiaSemana
                    where
                     num = zeller x y z
                     zeller x y z = (700 + (26 * x - 2) `div` 10
                          + d + y + y `div` 4 + z `div` 4 - 2 * z)
                          `mod` 7
                     (x,y,z)
                       | m <=2     = (m+10,(a-1)`mod`100,(a-1)`div`100)
                       | otherwise = (m-2 ,a    `mod`100,a    `div`100)

Jules
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to