Haskell:将 Double 类型的函数限制为仅适用于整数

标签 haskell types integer double

假设我正在编写一个函数,它接受一个整数列表并只返回列表中小于 5.2 的那些整数。我可能会做这样的事情:

belowThreshold = filter (< 5.2)

够简单了吧?但现在我想将此函数限制为仅使用 [Int] 类型的输入列表,这是出于我自己的设计原因。这似乎是一个合理的要求。唉,没有。限制类型的声明如下:
belowThreshold :: [Integer] -> [Integer]
belowThreshold = filter (< 5.2)

导致类型错误。那么这里有什么故事呢?为什么执行过滤器(< 5.2)似乎将我的输入列表转换为 double ?如何制作仅接受整数列表且仅返回整数列表的此函数的版本?为什么类型系统讨厌我?

最佳答案

在添加注释之前检查 ghci 中的 underThreshold 的推断类型:

> :t belowThreshold
belowThreshold :: [Double] -> [Double]

当您说“约束此功能”时,听起来您期望的是 Num a => [a] -> [a]。当您添加 [Integer] -> [Integer] 注释时,您实际上是在更改函数的类型。

要完成这项工作,请使用显式转换:
belowThreshold = filter ((< 5.2) . fromIntegral)

现在 belowThreshold :: [Integer] -> [Integer] 就像你想要的那样。但是在与 5.2 比较之前,整数被转换为 double 数。

那么为什么需要转换呢?类型错误可能误导了您:与 5.2 相比,整数列表没有转换为 double 数,真正的问题是只有 double 数可以与 double 数进行比较,因此您必须将 double 数列表传递给 belowThreshold 。 Haskell 没有隐式转换,甚至数字之间也没有。如果您想要转换,则必须自己编写。

I want to constrain this function to only work with input lists of type [Int] for design reasons of my own. This seems like a reasonable request.



好吧,从类型系统的角度来看,没有。这是合理的代码吗?
'c' < "foo"

那这个呢?
12 < "bar"

所有这些值都是 Ord 的实例,但您不能将它们与 (<) 一起使用。 Haskell 没有隐式转换。因此,即使两个值都是 NumOrd 的实例,如果它们的类型不同,您也无法将它们与 (<) 进行比较。

关于Haskell:将 Double 类型的函数限制为仅适用于整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2442840/

相关文章:

scala - 你能为基数排序制定一个幺半群或半群吗?

void 类型参数的 C++ 错误

haskell - 你如何在 Haskell 中使用 TypeApplications?

c++ - int 数组 C++ 的大小

java - 将 double 转换为 int

haskell - 在 Haskell 中定义枚举的更好方法

haskell - 镜片和 zipper 有什么区别?

haskell - 在这个回合制游戏中使用 Reader monad 是否正确?

scala - 定义方法以返回扩展它的类的类型

javascript - 在javascript中按原始顺序拆分整数并将其存储在数组中