Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 咖喱是否产生部分应用的功能?_Haskell_F#_Functional Programming - Fatal编程技术网

Haskell 咖喱是否产生部分应用的功能?

Haskell 咖喱是否产生部分应用的功能?,haskell,f#,functional-programming,Haskell,F#,Functional Programming,当前函数的结果是否为部分应用的函数?我理解currying是如何工作的,虽然我理解了部分函数应用程序是如何工作的,但我不清楚这些概念是否存在交叉 我的困惑源于以下引用,这与我之前对基于的概念的理解相冲突 简单地说,如果我们调用一个参数太少的函数,我们会得到 返回部分应用的函数,表示作为 我们遗漏了许多参数 举个例子(在F#中,尽管问题是关于函数式编程的) 在本例中,inc是部分应用的函数吗?简短回答:inc是通过部分应用获得的函数 curried函数的结果是目标语言中某种类型的值(Haskell

当前函数的结果是否为部分应用的函数?我理解currying是如何工作的,虽然我理解了部分函数应用程序是如何工作的,但我不清楚这些概念是否存在交叉

我的困惑源于以下引用,这与我之前对基于的概念的理解相冲突

简单地说,如果我们调用一个参数太少的函数,我们会得到 返回部分应用的函数,表示作为 我们遗漏了许多参数

举个例子(在F#中,尽管问题是关于函数式编程的)


在本例中,
inc
是部分应用的函数吗?

简短回答:
inc
是通过部分应用获得的函数

curried函数的结果是目标语言中某种类型的值(Haskell、F#或其他),因此它可能是函数(但也可能是整数、布尔值等,具体取决于您的声明)

关于部分应用程序。。。它只是返回其他函数的函数应用程序的一个名称,但从技术上讲,它和其他函数应用程序一样,都是函数应用程序。返回的函数基于前面的参数甚至不是必须的。以
\x->id
为例:您总是独立于输入
x

获得标识函数一般来说,curry意味着将一个双参数函数转换为一个接受一个参数并返回另一个单参数函数的函数,因此,使用第一个参数调用curried函数的结果和使用第二个参数调用curried函数的结果等价于使用两个参数调用原始(未结婚)函数。在带有闭包和动态类型(或类型推断)的伪C语言中,看起来是这样的:

// The original, uncurried function:
function f(a, b) { return 2 * a - b; }

// The curried function:
function g(a) {
    return function(b) {
        return f(a, b);
    }
}

// Now we can either call f directly:
printf("%i\n", f(23, 42));

// Or we can call the curried function g with one parameter, and then call the result
// with another:
printf("%i\n", (g(23))(42));
通过多次使用curry,我们可以将任何多参数函数简化为一组嵌套的单参数函数

在Haskell中,所有函数都是单参数的;像
fabc
这样的构造实际上相当于我们虚构的带闭包的c中的
((f(a))(b))(c)
。真正将多个参数传递到函数中的唯一方法是通过元组,例如
f(a,b,c)
——但由于curried函数的语法更简单,语义更灵活,因此很少使用此选项

Haskell Prelude定义了两个函数,
curry
uncurry
来在这两种表示之间进行转换:
curry
的类型是
((a,b)->c)->a->b->c
,也就是说,它接受一个单参数函数,该函数接受一个元组
(a,b)
,并返回一个
c
,并将其转换为
a->b->c
类型的函数,即接受
a
并返回接受
b
并返回
c
的函数<代码>未修剪则相反


部分应用不是一件真正的事情;它只是一个名称,用于表示您有一个curried函数(例如
fab
),而不是完全展开整个链(例如
f2342
),您在途中的某个地方停下来,并进一步传递结果函数,例如
让g=f23
。为了部分应用一个函数,它必须是curried(你不能部分应用
f(a,b)
as
let g=f(a)
),但是由于在Haskell中以curried方式编写函数是默认的,所以部分应用是很容易的,也是常见的做法。

投反对票,不发表评论?这只取决于你对它的看法。从形式上讲,没有“部分应用函数”这样的东西:
inc
是一个函数;这就是“它是什么”。我们认为它是一个“部分应用函数”,因为它也是表示
add
的部分应用程序的对象。我最初没有投反对票,但“我理解currying是如何工作的,部分函数应用程序是如何工作的”,然后问这个问题完全是胡说八道。@ildjarn抱歉,这个词说得不太好。调整了问题实际上,您可以部分应用uncarried函数。如果
f(a,b,c)={-…-}
,则部分应用
g(a,c)=f(a,2,c)
。通常,currying会转换类型为
a×b的函数→ c进入a→ (b)→ c) 
部分应用程序修复了一个(或多个)参数:
a×b×c→ d
转换为
a×c→ d
(例如)。
// The original, uncurried function:
function f(a, b) { return 2 * a - b; }

// The curried function:
function g(a) {
    return function(b) {
        return f(a, b);
    }
}

// Now we can either call f directly:
printf("%i\n", f(23, 42));

// Or we can call the curried function g with one parameter, and then call the result
// with another:
printf("%i\n", (g(23))(42));