我真的陷入了Haskell中的函数类型。有两种功能的类型,我无法解释它们之间的真正区别。
a :: Int -> (Int -> (Int -> (Int -> Int)))
b :: (((Int -> Int) -> Int) -> Int) -> Int
我仍然不明白这一点。我知道currying的目的是什么 - 但我在这个例子中看不到currying的概念!
函数a:传入Int
,结果是另一个传递Int
......等等。
功能b:这与功能A有什么不同?
答案 0 :(得分:7)
也许最好的办法是考虑两个更简单的功能:
f :: a -> (b -> c)
g :: (a -> b) -> c
让我们依次看看这些功能。
第一个函数f
采用类型为a
的单个参数,并返回类型为b -> c
的函数。换句话说,假设x :: a
,y :: b
和z :: c
,您可以编写如下内容:
f :: a -> (b -> c)
f x = f'
where f' :: b -> C
f' y = z
编写f
签名的另一种方法是:
f :: a -> b -> c
这是有效的,因为默认情况下我们将->
绑定到右侧。它还为我们提供了另一种理解f
的等效方法:它可以被认为是一个带有两个参数的函数,类型为a
和b
,并产生类型为{{1的结果}}。
第二个函数c
接受一个参数,它是g
类型的函数。
a -> b
因此两者非常不同。
将此函数应用于函数,第一个函数采用g :: (a -> b) -> c
g h = z
where h :: a -> b
类型的4个值并返回Int
。第二个函数采用类型Int
的单个函数,该函数采用类型((Int -> Int) -> Int) -> Int
的第三个函数并生成(Int -> Int)
,依此类推。
答案 1 :(得分:3)
函数b
将函数作为其参数 - 它不会生成函数作为其结果。这是一个很大的不同:
a 42
将生成一个带有其他参数的函数。 b 42
会产生类型错误,因为42
不是函数。 b myfun
myfun
类型为((Int -> Int) -> Int) -> Int)
的{{1}}会生成Int
。 a myfun
会导致类型错误,因为myfun
不是整数。