同样由于你的帮助,我在理解Haskell中的类型系统方面做了一些步骤。我仍然不明白的是这样的结构:
chk :: Eq b => (a -> b) -> a -> b -> Bool
'b'
,而您无法比较不同的类型?a
/ b
过去常常表示不同的类型?
如果我把这一切都搞错了,你能告诉我一个像这样的类型的功能吗?答案 0 :(得分:3)
这样的函数只能比较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
答案 1 :(得分:0)
您需要清楚地区分类型变量和正常变量之间的区别。
类型(Eq b) =>...
表示b
可以是任何类型,前提是该类型的值具有可比性。因此,b = Int
会起作用,因为我们可以比较Int
个值(例如,3 == 5
为false,但2 == 2
为真)。但是b = IO Int
不起作用,因为你无法比较I / O操作是否相等。
所有这些与无关a == b
; a
和b
都是类型,而不是值。该类型表示a
可以是任何类型,b
也可以是任何类型(如果它实现Eq
)。特别是,a
和b
可能相同的类型,但它们也可能是不同的类型。使用不同的类型变量表示这些可以是不同的类型,而不是必须不同。
答案 2 :(得分:0)
Ler看到我们如何从其类型中推断出i < arr.length
的合理实现。
有两个值,一个是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
也许还有十几个。