具有函数参数的函数是否已柯里化?
Is a function with a functional argument curried?
来自
In Haskell, it happens that everything is curried; all functions take just one argument (even uncurried functions in Haskell take a tuple, which is, strictly speaking, a single argument -- you might want to play with the curry and uncurry functions to see how that works).
我不确定这是否属实,但假设是这样。
如果一个函数接受另一个函数作为参数,那么它是柯里化的还是非柯里化的,就像一个函数接受一个元组或列表参数是非柯里化的? (一对元组类型是type1 x type2
,可以是type1^2
,而函数类型是type2^{type1}
,所以我觉得它们很相似)
如果未柯里化,我如何将这样的函数转换为柯里化函数?
If a function takes another function as an argument, is it curried or uncurried?
它只需要一个函数,所以只有一个参数,因此它是柯里化的。该参数是一个函数这一事实无关紧要。
例如map
这样的函数。 map
类型:
map :: (a -> b) -> ([a] -> [b])
因此它接受一个参数,一个函数(a -> b
类型),然后 returns 一个函数 [a] -> [b]
将映射 a
的列表通过应用该函数到 b
的列表。
所以map show :: Show a => [a] -> [String]
是这样的函数应用的结果,这又是一个函数。
是的,引用是正确的。所有关于 "curried" 和 "uncurried" functions 的讨论都是不精确的行话。
Haskell 是柯里化的 语言 。 Haskell 中的函数始终具有指数类型。如果一个参数是一个元组,没关系,它仍然只是一个值(恰好是一个元组)。
当我们将 (a,b) -> c
Haskell 函数视为 c a * b 时,这些概念是近似的一。但这只是我们做的心理体操。
实际上柯里化与否,是编程语言。例如,在 Lisp 中,
(lambda (a b) c)
实际上有类型c a * b并将它变成(c b)a函数我们需要把它通过一些改造。
实际上 Haskell 中没有 (\a b -> c)
lambda,只有 (\ a -> (\ b -> c))
嵌套的 lambda(*)。当我们在Haskell中写(\a b -> c)
时,它只是(\ a -> (\ b -> c))
的语法快捷方式。在 Haskell 中不可能有实际的 (\a b -> c)
lambda 函数,尽管它是通过具有 (\(a,b) -> c)
lambda 函数来近似的。
当您使用 lambda 函数实现自己的语言时,您在哪里真正看到了这一切的意义。
面对((lambda (a b) c) x y z)
函数调用,真正的问题是如何pair-up函数的参数和提供的值。
Haskell 将其转换为 ((let a=x in (let b=y in c)) z)
,但 Lisp 实际上将参数列表 (a b)
与值列表 (x y z)
配对并报告长度不匹配。
但是,作为未柯里化的语言,Lisp 可以在这里进行各种曲折和调整,例如可选参数、默认参数、命名参数等,以各种不同的方式将参数和值配对——不像 Haskell,总是 将 一个 参数与 一个一次提供价值。
(*) 还有一个重要的区别:[=101 中的 a
和 b
=]的(\ a -> (\ b -> c))
不是变量,而是模式。它们不仅像在 Lisp 中那样被分配了值——它们 与它们匹配 。
至少我能看到的真相是,几乎haskell中的每个值都可以看作是一个函数,并且每个函数当时只接受一个参数。让我们看一个例子(以 Int 为例,更清楚):
f :: Int -> Int -> Int -> Int
f x y z = x + y + z
f 可以看作是一个接受 Int
和 returns 的函数
Int -> (Int -> Int)
:t (f 2)
(f 2) :: Int -> Int -> Int
:t (f 2 3)
(f 2 3) :: Int -> Int
(f 2 3) 可以看作是一个接受 Int
和 return 一个 Int
的函数
终于
:t (f 2 3 4)
(f 2 3 4) :: Int
高阶函数示例:
h :: (Int -> Int -> Int) -> Int -> Int -> Int
h fn x y = fn x y
有点复杂,但思路相同:
:t (h f)
(h f) :: Int -> Int -> Int -> Int
(h f)
是一个函数,需要一个 Int
和 returning (Int -> Int -> Int -> Int)
但是……等等,它不是期待 return 一个函数吗?应该是这样
(h f) :: Int -> Int -> (Int -> Int)
好吧,说到点子上了。让我们继续
:t (h f 2)
(h f 2) :: Int -> Int -> Int
(h f 2)
是一个需要 Int
和 return 的函数 (Int -> Int)
最后
:t (h f 2 3)
(h f 2 3) :: Int -> Int
(h f 2 3)
确实是一个函数,期待一个 Int
, returning 一个 Int
(h f 2 3) 4 == 7
我认为这里的结论是,every function is curried in Haskell。
来自
In Haskell, it happens that everything is curried; all functions take just one argument (even uncurried functions in Haskell take a tuple, which is, strictly speaking, a single argument -- you might want to play with the curry and uncurry functions to see how that works).
我不确定这是否属实,但假设是这样。
如果一个函数接受另一个函数作为参数,那么它是柯里化的还是非柯里化的,就像一个函数接受一个元组或列表参数是非柯里化的? (一对元组类型是type1 x type2
,可以是type1^2
,而函数类型是type2^{type1}
,所以我觉得它们很相似)
如果未柯里化,我如何将这样的函数转换为柯里化函数?
If a function takes another function as an argument, is it curried or uncurried?
它只需要一个函数,所以只有一个参数,因此它是柯里化的。该参数是一个函数这一事实无关紧要。
例如map
这样的函数。 map
类型:
map :: (a -> b) -> ([a] -> [b])
因此它接受一个参数,一个函数(a -> b
类型),然后 returns 一个函数 [a] -> [b]
将映射 a
的列表通过应用该函数到 b
的列表。
所以map show :: Show a => [a] -> [String]
是这样的函数应用的结果,这又是一个函数。
是的,引用是正确的。所有关于 "curried" 和 "uncurried" functions 的讨论都是不精确的行话。
Haskell 是柯里化的 语言 。 Haskell 中的函数始终具有指数类型。如果一个参数是一个元组,没关系,它仍然只是一个值(恰好是一个元组)。
当我们将 (a,b) -> c
Haskell 函数视为 c a * b 时,这些概念是近似的一。但这只是我们做的心理体操。
实际上柯里化与否,是编程语言。例如,在 Lisp 中,
(lambda (a b) c)
实际上有类型c a * b并将它变成(c b)a函数我们需要把它通过一些改造。
实际上 Haskell 中没有 (\a b -> c)
lambda,只有 (\ a -> (\ b -> c))
嵌套的 lambda(*)。当我们在Haskell中写(\a b -> c)
时,它只是(\ a -> (\ b -> c))
的语法快捷方式。在 Haskell 中不可能有实际的 (\a b -> c)
lambda 函数,尽管它是通过具有 (\(a,b) -> c)
lambda 函数来近似的。
当您使用 lambda 函数实现自己的语言时,您在哪里真正看到了这一切的意义。
面对((lambda (a b) c) x y z)
函数调用,真正的问题是如何pair-up函数的参数和提供的值。
Haskell 将其转换为 ((let a=x in (let b=y in c)) z)
,但 Lisp 实际上将参数列表 (a b)
与值列表 (x y z)
配对并报告长度不匹配。
但是,作为未柯里化的语言,Lisp 可以在这里进行各种曲折和调整,例如可选参数、默认参数、命名参数等,以各种不同的方式将参数和值配对——不像 Haskell,总是 将 一个 参数与 一个一次提供价值。
(*) 还有一个重要的区别:[=101 中的 a
和 b
=]的(\ a -> (\ b -> c))
不是变量,而是模式。它们不仅像在 Lisp 中那样被分配了值——它们 与它们匹配 。
至少我能看到的真相是,几乎haskell中的每个值都可以看作是一个函数,并且每个函数当时只接受一个参数。让我们看一个例子(以 Int 为例,更清楚):
f :: Int -> Int -> Int -> Int
f x y z = x + y + z
f 可以看作是一个接受 Int
和 returns 的函数
Int -> (Int -> Int)
:t (f 2)
(f 2) :: Int -> Int -> Int
:t (f 2 3)
(f 2 3) :: Int -> Int
(f 2 3) 可以看作是一个接受 Int
和 return 一个 Int
终于
:t (f 2 3 4)
(f 2 3 4) :: Int
高阶函数示例:
h :: (Int -> Int -> Int) -> Int -> Int -> Int
h fn x y = fn x y
有点复杂,但思路相同:
:t (h f)
(h f) :: Int -> Int -> Int -> Int
(h f)
是一个函数,需要一个 Int
和 returning (Int -> Int -> Int -> Int)
但是……等等,它不是期待 return 一个函数吗?应该是这样
(h f) :: Int -> Int -> (Int -> Int)
好吧,说到点子上了。让我们继续
:t (h f 2)
(h f 2) :: Int -> Int -> Int
(h f 2)
是一个需要 Int
和 return 的函数 (Int -> Int)
最后
:t (h f 2 3)
(h f 2 3) :: Int -> Int
(h f 2 3)
确实是一个函数,期待一个 Int
, returning 一个 Int
(h f 2 3) 4 == 7
我认为这里的结论是,every function is curried in Haskell。