繁体   English   中英

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

[英]`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

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

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

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

或者

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

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

如果您在没有显式类型签名的情况下定义 function,则 Haskell 将推断出最通用的一个。 如果您不确定,这是弄清楚您的定义将如何被阅读的最简单方法; 然后,您可以将其复制到您的源代码中。 一个常见的错误是错误地输入了 function,然后在其他地方出现了令人困惑的类型错误。

无论如何,您可以通过在 ghci 中输入:i Num或阅读文档来获取有关Num class 的信息。 Num class 为您提供+*-negateabssignumfromInteger以及EqShow的每个 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 作为一种确定某物类型的技术。

编辑:评论后改变了我的答案。

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

如果您还有其他类似的问题,只需查看 class 类型的实例,以了解您希望能够在 function 中使用哪些类型。

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

使用 Num 而不是 Ord 没有任何优势。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM