类型签名为Integer / Int的函数:“类型整数与Int不匹配”

时间:2011-11-02 00:41:09

标签: haskell

有关

x :: Integer -> [a] -> [a]
x = take

y :: Integer -> [a] -> [a]
y _ [] = []
y n xs = take n xs

Hugs和GHC报告类型错误:

ERROR "test.hs":5 - Type error in application
*** Expression     : take n xs
*** Term           : n
*** Type           : Integer
*** Does not match : Int

ERROR "test.hs":8 - Type error in explicitly typed binding
*** Term           : x
*** Type           : Int -> [a] -> [a]
*** Does not match : Integer -> [a] -> [a]

这是因为“take”具有签名“Int - > ...”。有没有办法告诉类型系统直接将Integer转换为Int(没有fromIntegral),或者最好(保持Integer的非约束大小)“构造”take版本(或任何其他显式使用Int的函数) )对于整数?或者我是否必须编写自己的Prelude-Functions版本?目前,我的代码要么使用fromIntegral(并且如果整数大小超过Int的维度则不运行)或者标准函数的重复实现,并且感觉非常笨重。

2 个答案:

答案 0 :(得分:4)

使用Data.List中的genericTake代替。 “通用”列表函数接收Integer而不是Int。

将来,如果您想通过类型签名搜索Haskell函数,可以使用Hoogle


从更一般的意义上说,如果您只想添加转换步骤,则可以使用内置合成运算符轻松创建自己的函数。

--explicit type signature to force the less general types...
integerToInt :: Integer -> Int
integerToInt = fromIntegral

myGenericTake = take . integerToInt

--You can now use myGenericTake throughout the code.

答案 1 :(得分:1)

Haskell采用而非的方式进行任何隐式转换。因此,当您遇到take等函数时,只需需要即可使用fromIntegral或类似函数执行显式转换。

如果这会让你感到烦恼,那就表达你对改进前奏曲的看法。你肯定不会一个人希望改进Prelude功能。