是否可以说 "currying" 是 "partial application" 的反向动作?

Is it possible to tell that the "currying" is an action reverse of the "partial application"?

我通过阅读"Learn You a Haskell for Great Goog!"这本书来学习Haskell。我想确定我正确理解了 "currying".

我了解一个函数不能获得超过一个参数。当一个函数有一个以上的参数时,它 实际上 就像一个只有一个参数的函数一样工作。 IE。这个:

func :: Int -> Int -> Int -> Int

像这样工作(并且是一样的):

func :: Int -> (Int -> (Int -> Int))

即一个函数 returns 一个函数,那个 returns 也是一个函数,等等。这种 "nested doll" 行为称为 "currying"(柯里化函数)。代码的第一个变体就像 "syntax sugar".

任何参数大于零的函数都可以部分应用。 IE。可以看出 "currying" 是 "partial application" 的反向动作。我说得对吗?

没有

柯里化的反面是非柯里化

f :: a -> b -> c

f' :: (a, b) -> c
f' = -- uncurried f

f'' :: a -> b -> c
f'' = -- curried f' = f

柯里化函数,尽管它的 "language" 数量减少到 1,但保持 "semantic" 数量不变(因为您仍然必须为元组提供每个值)。比较中唯一改变的是你传递参数的方式。

部分应用是将函数的元数减少到大于0的应用。这是一个不可逆操作;你不能取消应用 参数。

--   1    2
f :: a -> b -> c

--    1
f' :: b -> c
f' = f c -- partially applied f

--     0 arguments
f'' :: c
f'' = f c1 c2 -- fully applied f

I.e. it is possible to tell that the "currying" is an action reverse of the "partial application".

几乎相反:"Currying" 可以看作 与 "partial application" 相同的东西

让我借助 ghci 会话进行解释。我们首先为不同类型的函数定义一些类型同义词。

Prelude> type Binary a b c = (a, b) -> c
Prelude> type Curried a b c = a -> (b -> c)
Prelude> type Unary a b = a -> b

在这里,我们有两种表示二元函数的方法:我们有 Binary 数学中的函数,即接受元组的函数。然后我们有 Curried 函数,就像通常在 Haskell 中一样,也就是说,函数 return 一个函数。为了完整起见,我们还为 Unary 函数指定了一个特殊名称。

现在我们可以使用标准的curryuncurry函数在二元函数的两种表示之间进行转换。在ghci中,我们可以这样检查:

Prelude> :t curry :: Binary a b c -> Curried a b c
curry :: Binary a b c -> Curried a b c
  :: Binary a b c -> Curried a b c

Prelude> :t uncurry :: Curried a b c -> Binary a b c
uncurry :: Curried a b c -> Binary a b c
  :: Curried a b c -> Binary a b c

(注意,当你输入:t foo :: SomeType,ghci会检查foo是否有类型SomeType。如果是,ghci会再次打印。如果不是,ghci会报错).

正如 Bartek 在他的回答中正确指出的那样,curry 的倒数是 uncurry。但是我们也可以这样理解curry的类型:

Prelude> :t curry :: Binary a b c -> a -> Unary b c
curry :: Binary a b c -> a -> Unary b c
  :: Binary a b c -> a -> Unary b c

如果我们这样写类型,我们看到我们可以使用 curry 来部分应用 Binary 函数:给定 f :: Binary a b c 和第一个参数 x :: a 我们可以使用 curry f x 产生一个 Unary b c ,它仍在等待类型为 b.

的第二个参数