1
votes

Level of Haskell : Newbie

Goal : Find the root of an element of the tree represented as a List

Input (Tree Nodes) (Positions in Array denote the node number) : [0,1,9,4,9,6,6,7,8,9]

Function invoked : getRoot 3

Expected Output : 9

Code :

li = [0,1,9,4,9,6,6,7,8,9]
getRoot::Integer->Integer
getRoot n | li!!n /= n    = getRoot li!!n
getRoot n | otherwise     = li!!n

Error Message :

ERROR file:.\test2.hs:111 - Type error in application
*** Expression     : li !! n
*** Term           : n
*** Type           : Integer
*** Does not match : Int

Compiler : WinHugs

Tried various combinations of 'Integers' and 'Int' to declare the type of the function. It seems that the array access returns an Integer but is then compared to an Int where it fails. Do not know why it does not convert Int to Integers.

Or is it something else all together ?

Searched on the internet, in the tutorials and on stackoverflow.

3
A bit of advice: If you're a beginner, don't use (!!) or any other index-based function on lists, including head, under any circumstances. If you think you need to use those functions, change your algorithm or use a different data structure instead. Continue to avoid these functions until you've learned Haskell well enough to know why I'm giving this advice.C. A. McCann
I'll keep this in mind. Will use recursion and the ':', '++' operators instead.Jack Brown
@JackBrown Writing your own copy of (!!) and using that does not count as not using (!!). =)Daniel Wagner

3 Answers

2
votes

(!!) has type [a] -> Int -> a. If you change the type signature of getRoot to Int -> Int, the code will compile:

li :: [Int]
li = [0,1,9,4,9,6,6,7,8,9]

getRoot::Int->Int
getRoot n | li!!n /= n    = getRoot (li!!n)
getRoot n | otherwise     = li!!n

Testing:

> getRoot 3
9
6
votes

The type of the indexing function, (!!), is:

Prelude> :t (!!)
(!!) :: [a] -> Int -> a

the index must be of type Int.

You have a type :

getRoot::Integer->Integer

where you index, n , is an Integer. You must convert it to an Int to use as an index.

This can be done two ways:

Also, you should upgrade to GHC and The Haskell Platform, as Hugs is an unmaintained, obsolete version of Haskell.

1
votes

The type of (!!) is

(!!) :: [a] -> Int -> a 

In other words, the second argument it accepts should be an Int, not an Integer. They're different types. If you change your type signature around to accept an Int instead, this error will go away.

Also, in order for this to work, your li must be a list of Ints. You can do this by simply adding a type signature:

li :: [Int]
li = [0,1,9,4,9,6,6,7,8,9]

With that, all should be well. Good luck!