functionhaskellrecursionswitch-statementhaskell-prelude

Im having an error with Haskell with cases that i cant find


So im trying to create this function AgregarMon that basically adds a "Monomio" to "Polinomio" Monomio would end up being an element inside Polinomio which is a list. You are going to understand better in a little bit

type Monomio = (Int, Int)
type Polinomio = [Monomio]

agregarMon :: Monomio -> Polinomio -> Polinomio
agregarMon = \m p -> case m of{ (0,0) -> p;
                                 x -> case p of{[] -> [x];
                                                y:ys -> case (snd x == snd y) of { true -> case ((fst x + fst y)==0) of { true -> ys;
                                                                                                                          false -> (fst x + fst y , snd x):ys;}
                                                                                   false -> case snd x < snd y of{true -> y: agregarMon x ys;
                                                                                                                  false -> x:y:ys;}}}}

I've been looking at my code like an hour, and i cant find the problem. The error says:

Polinomios.hs:45:140: error:
    Unexpected case expression in function application:
        case ((fst x + fst y) == 0) of
          true -> ys
          false -> (fst x + fst y, snd x) : ys
    You could write it with parentheses
    Or perhaps you meant to enable BlockArguments?
   |
45 |                                                                                                 y:ys -> case (snd x == snd y) of { true -> case ((fst x + fst y)==0) of { true -> ys;    |                                                                                                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...

Line 45 is the fourth line on the code from above. Im sorry if im missing info, please let me now. Just in case, someone doesnt knows, fst and snd are on the Prelude. fst takes the first element from a "Monomio" snd the second one. fst = (a,b)->a snd (a,b) -> b


Solution

  • case (snd x == snd y) of { true ->
    

    is wrong: true here is just a variable name, unrelated to the constructor True (with a capital T!). The snippet above is therefore equivalent to

    case (snd x == snd y) of { x ->
    

    Hence, the pattern matches any boolean value, True and False. For that reason the other branch false -> ... will never be considered.

    I recommend you turn on warnings, since doing so makes GHC report the second branch as redundant code. The fact that the compiler considers a branch useless signals that something is very wrong with the code.

    As a final note, in my experience code like

    case something of
      True  -> a
      False -> b
    

    is not common, since we can write it as

    if something
    then a
    else b
    

    which is easier to read, in my view.