有关
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的维度则不运行)或者标准函数的重复实现,并且感觉非常笨重。
答案 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功能。