使用 '!!' 从列表中访问 Int/Integer 元素时出错



Haskell等级:新手

目标:查找表示为List 的树的元素的根

输入(树节点)(数组中的位置表示节点编号):[0,1,9,4,9,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

错误消息

错误文件:。\test2.hs:111-应用程序中的类型错误***表情:李!!n***期限:n***类型:Integer***不匹配:Int

编译器:WinHugs

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

还是其他的东西加在一起?

在互联网、教程和stackoverflow上搜索。

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

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

索引的类型必须是CCD_ 2。

你有一个类型:

getRoot::Integer->Integer

索引所在的n是一个Integer。必须将其转换为Int才能用作索引。

这可以通过两种方式实现:

  • 使用fromInteger进行转换
  • 使用genericIndex

此外,您应该升级到GHC和Haskell平台,因为Hugs是Haskell的一个未维护、过时的版本。

(!!)的类型为[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

(!!)的类型是

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

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

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

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

有了这些,一切都会好起来的。祝你好运

最新更新