首页 > 解决方案 > Type variables in function signature

问题描述

If I do the following

functionS (x,y) = y
:t functionS
functionS :: (a, b) -> b

Now with this function:

functionC x y = if (x > y) then True else False
:t function

I would expect to get:

functionC :: (Ord a, Ord b) => a -> b -> Bool

But I get:

functionC :: Ord a => a -> a -> Bool

GHCI seems to be ok with the 2 previous results, but why does it give me the second? Why the type variable a AND b aren't defined?

标签: haskell

解决方案


我认为您可能误读了类型签名。不是你自己的错——你用来说明你的想法的例子有点令人困惑。特别是,在您的元组示例中

functionS :: (a,b) -> b
functionS (x,y) = y

这个符号(_,_)意味着两个不同的东西。在第一行中,(a,b)指的是type,它的第一个元素具有 typea并且第二个元素具有 type 的对的类型b。在第二行中,(x,y)指的是一个特定的对,其中xhas typeayhas type b。虽然这个“双关语”提供了一个有用的助记符,但当您第一次掌握它时,它可能会让人感到困惑。我宁愿对的类型是常规类型构造函数:

functionS :: Pair a b -> b
functionS (x,y) = y

所以,继续你的问题。在签名中给你

functionC :: Ord a => a -> a -> Bool

a是一种类型Ord a表示该类型的元素彼此之间a是可排序的。该函数接受两个相同类型的参数。一些可排序的类型是(数字上的)、(字典上的)和其他一些类型。这意味着您可以分辨出两个s 中哪个更小,或者两个s 中哪个更小。但是我们不一定知道如何判断 an是否小于 a (这很好!你见过什么样的恶作剧IntegerStringIntegerStringIntegerStringjavascript 必须做些什么来支持无类型平等?Haskell 根本不需要解决这个问题!)。所以这就是这个签名的意思——只有一个可排序的类型,a,并且该函数接受两个相同类型的元素。

您可能仍然想知道为什么functionS的签名有两个不同的类型变量。这是因为没有约束将它们限制为相同,例如必须对它们进行排序。 functionS与两个组件都是整数的一对同样适用,就像一个是整数而另一个是字符串时一样。没关系。Haskell 总是选择最通用的类​​型。因此,如果不强迫它们相同,它们就会不同。

有更多的技术方法可以解释这一切,但我觉得直观的解释是有序的。我希望它有帮助!


推荐阅读