3
data Tree a = Branch a a | Leaf deriving (Show)

construct :: (Integral a) => [a] -> Tree a
construct [] = Leaf
construct (x:[]) = Leaf                -- _____error________
construct (l:r:xs) = if l>r then Branch l (construct $ r:xs) 
                            else Branch (construct $ l:xs) r
* Occurs check: cannot construct the infinite type: a ~ Tree a
* In the second argument of `Branch', namely `(construct $ r : xs)'
  In the expression: Branch l (construct $ r : xs)
  In the expression:
    if l > r then
        Branch l (construct $ r : xs)
    else
        Branch (construct $ l : xs) r
* Relevant bindings include
    xs :: [a] (bound at C:\Stuff\code\New folder (2)\try.hs:69:16)
    r :: a (bound at C:\Stuff\code\New folder (2)\try.hs:69:14)
    l :: a (bound at C:\Stuff\code\New folder (2)\try.hs:69:12)
    construct :: [a] -> Tree a

why was it infinite type? This "infinite type" is input or output?

and also, If I change the construct (x:[]) = Leaf to construct (x:[]) = x then the error occurs in that x. Why?

Will Ness
  • 70,110
  • 9
  • 98
  • 181

1 Answers1

6

Let's start from the beginning:

data Tree a = Branch a a | Leaf deriving(Show)

This "tree", by definition, will contain exactly two a values (in a Branch) or none at all (Leaf). I'm not sure about why this is called a tree. It looks like this is not what you intended to do. Maybe you wanted

data Tree a = Branch (Tree a) (Tree a) | Leaf a deriving(Show)

which is a tree with a values in the leaves. Or, alternatively,

data Tree a = Branch a (Tree a) (Tree a) | Leaf deriving(Show)

which is a tree with a values in the internal nodes.

Anyway, let's address your issue:

construct :: (Integral a) => [a] -> Tree a
construct (l:r:xs) = if l>r then Branch l (construct $ r:xs) else ...

Here, l has type a. Also, construct $ r:xs produces a value of type Tree a. Hence these have different types: a vs Tree a.

You then take this two values and pass them to Branch which, by definition, tales two values of the same type. The compiler tries to solve the type equality

 a ~ Tree a

but this immediately fails, since the only solution would be the non-existent infinite type

a = Tree (Tree (Tree ...))

Finally, to fix your code, you will need to modify your tree type so that it is actually a tree. After that, you will need to adapt your construct code to your new type.


If I change the construct (x:[]) = Leaf to construct (x:[]) = x then the error occurs in that x. Why?

Because x has type a, yet the signature of construct promises a Tree a, hence requiring a ~ Tree a as in the previous case.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
chi
  • 111,837
  • 3
  • 133
  • 218