简体   繁体   English

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

[英]Functions with type signature Integer/Int: “type Integer does not match Int”

For 对于

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

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

both Hugs and GHC report type errors: 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]

This is due to the fact that "take" has the signature "Int -> ...". 这是因为“take”具有签名“Int - > ......”。 Is there a way to tell the type system to either convert Integer to Int directly (without fromIntegral), or preferably (to keep the non-constrained size of Integer) to "construct" a version of take (or any other function explicitly using Int) for Integer? 有没有办法告诉类型系统直接将Integer转换为Int(没有fromIntegral),或者最好(保持Integer的非约束大小)“构造”take版本(或任何其他显式使用Int的函数) )对于整数? Or do I have to write my own versions of Prelude-Functions? 或者我是否必须编写自己的Prelude-Functions版本? Currently, my code is either littered with fromIntegral (and doesn't run if the Integer size exceeds the dimensions of Int) or with trivial re-implementations of standard functions, and that feels very clunky. 目前,我的代码要么使用fromIntegral(如果Integer大小超过Int的维度则不会运行)或者标准函数的重复实现,并且感觉非常笨重。

Use genericTake from Data.List instead. 请改用Data.List中的genericTake。 The "generic" list functions receive Integer instead of the Int. “通用”列表函数接收Integer而不是Int。

In the future, if you want to search for Haskell functions by type signature you can use Hoogle 将来,如果要按类型签名搜索Haskell函数,可以使用Hoogle


In a more general sense, if all you want to do is add a conversion step you can use the built in composition operator to easily create your own functions. 从更一般的意义上讲,如果您只想添加转换步骤,则可以使用内置合成运算符轻松创建自己的函数。

--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.

Haskell takes the approach of not making any implicit casts. Haskell采用进行任何隐式转换的方法。 So when you are stuck with functions like take , you simply need to perform the explicit cast using fromIntegral or similar. 因此,当您遇到像take这样的函数时,您只需要使用fromIntegral或类似函数执行显式转换。

If that bugs you, then voice your opinion about improving Prelude. 如果这会让你烦恼,那就表达你对改进Prelude的看法。 You would certainly not be alone in hoping for improved Prelude functions. 你肯定不会孤军奋战,希望改进Prelude功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM