[英]`Ord a =>` or `Num a =>`
我有以下功能:
which (x:xs) = worker x xs
worker x [] = x
worker x (y:ys)
| x > y = worker y ys
| otherwise = worker x ys
并且想知道我应该如何定义上述函数which
和worker
的类型签名?
例如,以下哪种方式最适合作为 worker 的类型签名?
worker:: Num a => a -> [a] -> a
,
或者
worker:: Ord a => a -> [a] -> a
?
我真的很困惑,不知道我应该选择哪三个。 我很感激你的想法。 谢谢。
如果您在没有显式类型签名的情况下定义 function,则 Haskell 将推断出最通用的一个。 如果您不确定,这是弄清楚您的定义将如何被阅读的最简单方法; 然后,您可以将其复制到您的源代码中。 一个常见的错误是错误地输入了 function,然后在其他地方出现了令人困惑的类型错误。
无论如何,您可以通过在 ghci 中输入:i Num
或阅读文档来获取有关Num
class 的信息。 Num
class 为您提供+
、 *
、 -
、 negate
、 abs
、 signum
、 fromInteger
以及Eq
和Show
的每个 function 。 注意<
和>
不存在! 要求Num
的值并尝试比较它们实际上会产生类型错误——不是每种类型的数字都可以比较。
所以它应该是Ord a =>...
,因为Num a =>...
如果你尝试它会产生类型错误。
如果您考虑一下您的函数的作用,您会看到which xs
返回xs
中的最小值。 什么可以有最小值? 可排序的Ord
的列表!
问 ghci 看看它说什么。 我只是将您的代码原样复制粘贴到一个文件中并将其加载到 ghci 中。 然后我使用:t
这是一个特殊的 ghci 命令来确定某物的类型。
ghci> :t which
which :: (Ord t) => [t] -> t
ghci> :t worker
worker :: (Ord a) => a -> [a] -> a
在大多数情况下,Haskell 的类型推断非常聪明。 学会相信它。 其他答案充分涵盖了为什么在这种情况下应该使用Ord
; 我只是想确保明确提到 ghci 作为一种确定某物类型的技术。
编辑:评论后改变了我的答案。
这取决于您希望能够比较的内容。 如果您希望能够比较Double
、 Float
、 Int
、 Integer
和Char
,请使用Ord
。 如果您只想能够比较Int
,那么只需使用Int
。
如果您还有其他类似的问题,只需查看 class 类型的实例,以了解您希望能够在 function 中使用哪些类型。
我总是 go 与 Ord 类型约束。 它是最通用的,因此可以更频繁地重复使用。
使用 Num 而不是 Ord 没有任何优势。
Int 可能有一个小的优势,因为它不是多态的并且不需要字典查找。 如果我需要性能,我仍然会使用 Ord 并使用specialize pragma。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.