Haskell:通过类型定义找出函数
也是由于你的全部帮助,我在理解Haskell中的类型系统方面做了一些步骤。我仍然不明白的是这样的结构:Haskell:通过类型定义找出函数
chk :: Eq b => (a -> b) -> a -> b -> Bool
- 为什么只在
'b'
类约束,而你无法比较不同类型的? - 是不是
a
/b
反正用来表示不同类型? 如果我弄错了所有这些,你能告诉我一个函数吗?
这样的函数只能比较b
类型的两个值是否相等,不涉及a
。
如果你看的类型,有一个实现,它似乎是明显的:
chk :: Eq b => (a -> b) -> a -> b -> Bool
chk f x y =
let z = f x -- z :: b
in y == z -- comparison of two values of type b
你需要明确在你的心中的差异类型变量和正常变量之间的分离 。
类型(Eq b) =>...
意味着b
可以是任何类型,只要该类型的值是相当的。所以b = Int
会工作,因为我们可以比较Int
的值(例如,3 == 5
是错误的,但2 == 2
是正确的)。但b = IO Int
不起作用,因为您无法比较I/O操作是否相等。
这一切都有无关是否a == b
; a
和b
都是类型,而不是值。该类型表示a
可以是任何类型,并且b
也可以是任何类型(如果它实现了Eq
)。特别是,a
和b
可能是类型相同的类型,但它们也可能是不同的类型。使用不同类型的变量表示这些可以是是不同的类型,不是它们必须是不同的。
Ler's了解我们如何从其类型推导出chk
的合理实现。
有两个值,其中一个类型为a
和b
类型之一,我们不能用它们做很多事情。两种类型都是未知的。 (它们实际上可能是同一类型,但我们不知道)。我们知道我们可以比较b
类型的两个值是否相等,但在我们的处理中只有一个这样的值。我们可以将其与自身进行比较,但这没有多大意义。如果我们有b
类型的另一个值,我们可以比较两者。
但有三个参数,其中一个是a
,一个是b
,另一个是a->b
类型的函数。除此之外,我们可以对它们做的唯一其他事情是将函数应用于类型为a
的值。此应用程序的结果为b
。但是等等,这正是我们想要的,另一个值为b
的值来完成比较。由于比较的结果是Bool
,这正是我们需要完成的chk
。
chk f x y = f x == y
这是编写这个函数的两个不平凡的方法之一。另一个用/=
替代==
。
实际上这种类型的函数非常有限,我们可以枚举它们。如果你只考虑到总的功能和要求平等是自反且对称,那么只有两个这种类型的其他功能:
chk0 f x y = True
chk1 f x y = False
如果你把这些限制,你也可以写:
chk2 f x y = undefined
chk3 f x y = y == y // may be different from just True
chk4 f x y = f x == f x
也许还有十几个。
'chk f x y = f x == y'只需要'f x'和'y'与'=='相媲美,它们都是'b',所以'Eq b'就是所有必需的。 – Ryan
另请注意,'a'和'b'可能是相同的类型 - 它们不必是不同的(也不必相同)。 – chi
'方程b''表示某些类型'b'的*值*可以进行比较以得到相等的结果(例如'=='的具体实现。所以你是对的,类型变量已经指出哪些值必须是相同的类型;但是一个'b'可能是(0 :: Int),另一个(42 :: Int) – jberryman