1

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.

2
  • 1
    It seems like you just want to compare according to lexicographical ordering. You can do that by using the compare instance for tuples: compare (CNode left1 v1 right1) (CNode left2 v2 right2) = compare (v1, left1, right1) (v2, left2, right2) Commented May 13, 2014 at 17:24
  • If you still want to write it out explicitly (rather than using @user2407038's trick): Since you are comparing v1 and v2 all three ways it would probably be clearer (and more efficient) to use case v1 `compare` v2 of ... instead of nested ifs. Commented May 13, 2014 at 22:45

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.