Haskell:通过类型定义找出函数

Haskell:通过类型定义找出函数

问题描述:

也是由于你的全部帮助,我在理解Haskell中的类型系统方面做了一些步骤。我仍然不明白的是这样的结构:Haskell:通过类型定义找出函数

chk :: Eq b => (a -> b) -> a -> b -> Bool 
  • 为什么只在'b'类约束,而你无法比较不同类型的?
  • 是不是a/b反正用来表示不同类型? 如果我弄错了所有这些,你能告诉我一个函数吗?
+2

'chk f x y = f x == y'只需要'f x'和'y'与'=='相媲美,它们都是'b',所以'Eq b'就是所有必需的。 – Ryan

+1

另请注意,'a'和'b'可能是相同的类型 - 它们不必是不同的(也不必相同)。 – chi

+1

'方程b''表示某些类型'b'的*值*可以进行比较以得到相等的结果(例如'=='的具体实现。所以你是对的,类型变量已经指出哪些值必须是相同的类型;但是一个'b'可能是(0 :: Int),另一个(42 :: Int) – jberryman

这样的函数只能比较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; ab都是类型,而不是。该类型表示a可以是任何类型,并且b也可以是任何类型(如果它实现了Eq)。特别是,ab可能是类型相同的类型,但它们也可能是不同的类型。使用不同类型的变量表示这些可以是是不同的类型,不是它们必须是不同的。

Ler's了解我们如何从其类型推导出chk的合理实现。

有两个值,其中一个类型为ab类型之一,我们不能用它们做很多事情。两种类型都是未知的。 (它们实际上可能是同一类型,但我们不知道)。我们知道我们可以比较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 

也许还有十几个。