`Ord a =>`或`Num a =>`

时间:2011-06-12 13:35:22

标签: list function haskell types type-signature

我有以下功能:

which (x:xs) = worker x xs
worker x [] = x
worker x (y:ys)
    | x > y      = worker y ys
    | otherwise  = worker x ys

我想知道如何定义上述函数whichworker的类型签名?

例如,以下哪种方式最适合作为工作人员的类型签名

worker :: Num a => a -> [a] -> a

worker :: Ord a => a -> [a] -> a

我真的很困惑,不知道我应该选择哪三个。我很感激你的想法。感谢。

5 个答案:

答案 0 :(得分:6)

如果定义没有显式类型签名的函数,Haskell将推断出最常见的类型。如果您不确定,这是了解如何阅读您的定义的最简单方法;然后,您可以将其复制到源代码中。一个常见的错误是错误地键入一个函数,然后在其他地方出现令人困惑的类型错误。

无论如何,您可以通过在ghci中输入Num或阅读文档来获取:i Num课程的信息。 Num课程为您提供+*-negateabssignumfromInteger ,以及EqShow的所有功能。请注意,<>不存在!要求Num的值并尝试比较它们实际上会产生类型错误 - 不是每种数字都可以比较。

所以它应该是Ord a => ...,因为Num a => ...如果你尝试了它会产生类型错误。

答案 1 :(得分:3)

如果您考虑一下您的功能,您会发现which xs会返回xs中的最小值。什么可以有最低价值?一个Ord可用的东西列表!

答案 2 :(得分:2)

询问ghci,看看它的内容。我只是将您的代码复制粘贴到文件中并将其加载到ghci中。然后我用:t这是一个特殊的ghci命令来确定某事物的类型。

ghci> :t which
which :: (Ord t) => [t] -> t
ghci> :t worker
worker :: (Ord a) => a -> [a] -> a

Haskell的类型推断在大多数情况下非常聪明;学会信任它。其他答案足以涵盖在这种情况下应该使用Ord的原因;我只是想确保ghci被明确地提到作为确定某事物类型的技术。

答案 3 :(得分:0)

修改:评论后改变了我的回答。

这取决于您想要比较的内容。如果您希望能够比较DoubleFloatIntIntegerChar,请使用Ord。如果您只想比较Int,请使用Int

如果您有另外这样的问题,只需查看类型类的实例,以告知您希望在函数中使用哪些类型。

答案 4 :(得分:0)

我总是使用Ord类型约束。它是最通用的,因此可以更频繁地重复使用。

使用Num over Ord没有任何优势。

Int可能有一个小优势,因为它不是多态的,也不需要字典查找。如果我需要性能,我会使用Ord并使用specialize pragma。