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上进行搜索。
答案 0 :(得分:6)
索引函数(!!)
的类型是:
Prelude> :t (!!)
(!!) :: [a] -> Int -> a
索引必须是Int
类型。
你有一个类型:
getRoot::Integer->Integer
您的索引n
是Integer
。您必须将其转换为Int
才能用作索引。
这可以通过两种方式完成:
fromInteger
另外,你应该升级到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]
有了这个,一切都应该好。祝你好运!