假设我想编写一个函数来判断给定的整数是否为素数,我应该使用哪种类型的签名?
isPrime :: Int -> Bool
Run Code Online (Sandbox Code Playgroud)
要么
isPrime :: (Integral a) => a -> Bool
Run Code Online (Sandbox Code Playgroud)
有什么不同?是否有特别的理由选择一个而不是另一个?
如果是这样,我应该在哪些情况下分别使用这两种?
C. *_*ann 11
该类型Int -> Bool
意味着您的函数对类型的值进行操作Int
,这些值是大小限制的整数(我认为最大大小取决于机器).
该类型(Integral a) => a -> Bool
意味着您的函数对具有类型类实例的任何类型的值进行操作Integral
- 即,以特定方式表现为整数的类型.选择具体类型的主要原因是创建一个更通用的功能.
Integral
当您需要在其他上下文中使用类似整数的类型时,使用通用表单最有用 - 一个很好的示例是标准库无法执行此操作的地方,例如函数replicate :: Int -> a -> [a]
.对于某些特定的类似整数类型的代码,为了自己的目的而想要使用该类型,replicate
因此需要转换为Int
first或import genericReplicate
from Data.List
.
在您的情况下,您可能需要考虑的是类型Integer
,它表示任意大小的整数.由于您的主要目标是计算,因此支持任意整数类型的价值较小.
如果没记错的话,唯一的实例Integral
在标准库Int
和Integer
进不去.(编辑:正如哈马尔在评论中提醒我的那样,在Data.Int
和Data.Word
中也有固定大小类型的例子.也有外国类型,CInt
但我有意无视这些.)