使用'!!'从List访问Int / Integer元素时出错

时间:2012-09-26 15:58:26

标签: list haskell

Haskell级别:新手

目标:        找到表示为List

的树的元素的根

输入(树节点)(数组中的位置表示节点编号):      [0,1,9,4,9,6,6,7,8,9]

调用的功能:      getRoot 3

预期输出:      9

代码

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 file:.\test2.hs:111 - Type error in application
*** Expression     : li !! n
*** Term           : n
*** Type           : Integer
*** Does not match : Int

编译器:WinHugs

尝试了'Integers'和'Int'的各种组合来声明函数的类型。 似乎数组访问返回一个Integer,但然后与它失败的Int进行比较。不知道为什么它不将Int转换为Integers。

或者它还是其他什么东西?

在互联网上,在教程中和在stackoverflow上进行搜索。

3 个答案:

答案 0 :(得分:6)

索引函数(!!)的类型是:

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

索引必须是Int类型。

你有一个类型:

getRoot::Integer->Integer

您的索引nInteger。您必须将其转换为Int才能用作索引。

这可以通过两种方式完成:

另外,你应该升级到GHC和The Haskell Platform,因为Hugs是一个没有维护的,过时的Haskell版本。

答案 1 :(得分:2)

(!!)的类型为[a] -> Int -> a。如果您将getRoot的类型签名更改为Int -> Int,则代码将编译:

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

测试:

> getRoot 3
9

答案 2 :(得分:1)

(!!)的类型是

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

换句话说,它接受的第二个参数应该是Int,而不是Integer。他们是不同的类型。如果您更改类型签名以接受Int,则此错误将消失。

此外,为了实现此目的,您的li必须是Int的列表。您只需添加类型签名即可完成此操作:

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

有了这个,一切都应该好。祝你好运!