uncurry f=\(a,b)->f a b
uncurry
将柯里化(Currying)函数转换为对函数,但上面的函数只是将其转换为柯里化(Currying)函数 f a b
。这不是与 uncurry
函数的定义相矛盾吗?
最佳答案
pelotom和Chuck说的100%正确。我认为您在某些时候对 curry 与 uncurry 以及函数定义有点困惑。
<小时/>我们知道柯里化(Currying)函数是这样的:
add x y = x + y
它的定义是:
add :: (Num a) => a -> a -> a
添加需要 Num
,并返回一个采用 Num
的函数并返回 Num
.
通过这种方式,我们可以获得一个部分应用函数,例如
add3 = add 3
感谢add
被柯里化(Currying)后,当我们只能传递一个参数(在本例中为 3)时,我们可以返回一个带有 Num
的函数。并返回 Num
.
>add3 5
8
非柯里化(Currying)函数采用元组,或分组在一起的值,例如 (1,2)。 (注意,元组不必成对。您可以拥有 (1,2,3,4,5) 形式的元组。只是常规的旧 uncurry 处理特定的对)。如果我们将添加更改为非柯里化(Currying),则会是:
add :: (Num t) => (t, t) -> t
add (x, y) = x + y
这需要两个元组 Num
s 并返回一个 Num。我们不能像使用 add 作为柯里化(Currying)函数那样部分应用它。它需要两个参数,并在元组中传递。
现在,进入 uncurry 函数! (如果您想知道函数的类型,请在 GHCi 中使用 :t <some function>
,或使用 Hoogle )。
uncurry :: (a -> b -> c) -> ((a, b) -> c)
uncurry f=\(a,b)->f a b
那么我们从中知道什么呢?它采用 f,我们从定义中注意到它是来自 (a->b->c) 的柯里化(Currying)函数,并且它返回一个非柯里化(Currying)函数强>((a,b)->c)。
如果我们向 uncurry 提供 curry 添加(记住: add x y
),我们会得到什么?
我们得到一个匿名函数,或 lambda 函数,它接受一个元组,并应用该元组的值 a
和b
,对于我们的函数,add
.
f a b
并不意味着我们得到了一个函数——你会看到 ->
如果是这样的话。我们只是得到 f
的值与 a
和b
.
这有点像我们手动完成此操作:
tupleAdd (a,b) = add a b
但是uncurry
为我们完成了这一切,我们可以继续使用原始柯里化(Currying)函数的全新非柯里化(Currying)形式。
很酷吧?
关于haskell - uncurry 函数的类型签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4754417/