Niklas R
Niklas R

Reputation: 16900

Haskell Syntax Error with nested ifs

I'm trying to do my homework but I get a syntax error that I don't understand.

data CTree a b =
        CNode (CTree a b) b (CTree a b) | -- left, value, right
        CLeaf a                           -- value
    deriving (Show, Ord)

-- a)
--

instance (Ord a, Ord b) => Ord (CTree a b) where

    --
    -- Compares two CNode objects
    --
    (CNode left1 v1 right1) `compare` (CNode left2 v2 right2) =

        -- If the value of the first node is greater than
        -- the value of the second node, the result is GT.
        if (v1 > v2) then GT

        -- If the value of the first node is smaller than
        -- the value of the second node, the result is LT
        else if (v2 < v1) then LT

        -- We must compare the child nodes if the values of
        -- boths nodes equal.
        else if (v1 == v2) then

            if (left1 == left2) then
                (right1 `compare` right2)
            else
                (left1 `compare` left2)

main = do
    print "foo"

The error is (at the line of main = do)

parse error (possibly incorrect indentation or mismatched brackets)

I am aware that there are some overloads of the compare function missing, but the Syntax Error should not originate from that fact.

Upvotes: 1

Views: 71

Answers (2)

chi
chi

Reputation: 116174

In your code, if (v1 == v2) has a then branch but lacks an else one. You should remove that if, which serves no purpose since you checked for v1 < v2 and v1 > v2 before.

Upvotes: 4

Shoe
Shoe

Reputation: 76308

You should indent:

if (left1 == left2) then
    (right1 `compare` right2)
else
    (left1 `compare` left2)

one more layer, and provide an else for the corresponding if (v1 == v2) then.

Then you should remove Ord from the deriving and add an Eq instead. And since your b type is an Ord you can just rewrite your program as:

data CTree a b =
        CNode (CTree a b) b (CTree a b) |
        CLeaf a
    deriving (Show, Eq)

instance (Ord a, Ord b) => Ord (CTree a b) where
    (CNode _ v1 _) `compare` (CNode _ v2 _) = v1 `compare` v2

main = do
    print "foo"

Live demo

It is to notice that I've changed the meaning of the compare function for CTree as you described it, because your function would never return EQ, which is actually an expected value.

But if you want to keep that behavior you can just do:

instance (Ord a, Ord b) => Ord (CTree a b) where
    (CNode left1 v1 right1) `compare` (CNode left2 v2 right2) =
        if (v1 == v2) then
            if (left1 == left2) then
                (right1 `compare` right2)
            else
                (left1 `compare` left2)
        else v1 `compare` v2

Live demo

Upvotes: 1

Related Questions