整数的haskell类型签名

man*_*ang 10 haskell

假设我想编写一个函数来判断给定的整数是否为素数,我应该使用哪种类型的签名

  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因此需要转换为Intfirst或import genericReplicatefrom Data.List.

在您的情况下,您可能需要考虑的是类型Integer,它表示任意大小的整数.由于您的主要目标是计算,因此支持任意整数类型的价值较小.

如果没记错的话,唯一的实例Integral在标准库IntInteger进不去.(编辑:正如哈马尔在评论中提醒我的那样,在Data.IntData.Word中也有固定大小类型的例子.也有外国类型,CInt但我有意无视这些.)