我试图了解在Scala中讨论部分应用程序的优点.请考虑以下代码:
def sum(f: Int => Int) = (a: Int, b: Int) => f(a) + f(b)
def sum2(f: Int => Int, a: Int, b: Int): Int = f(a) + f(b)
def sum3(f: Int => Int)(a: Int, b: Int): Int = f(a) + f(b)
val ho = sum({identity})
val partial = sum2({ identity }, _, _)
val currying = sum3({ identity })
val a = currying(2, 2)
val b = partial(2, 2)
val c = ho(2, 2)
Run Code Online (Sandbox Code Playgroud)
那么,如果我可以轻松计算部分应用的功能,那么currying的优点是什么?
如何使用参数数组调用Function.prototype.bind,而不是硬编码参数?(不使用ECMA6,因此没有传播运营商).
我试图在使用回调的模块周围放置一个promises包装器,我想绑定传递给我的包装器方法的所有参数并绑定它们.然后我想用我自己的回调调用部分应用的绑定函数,它将解析或拒绝一个promise.
var find = function() {
var deferred, bound;
deferred = Q.defer();
bound = db.find.bind(null, arguments);
bound(function(err, docs) {
if(err) {
deferred.fail(err);
} else {
deferred.resolve(docs);
}
});
return deferred.promise;
}
Run Code Online (Sandbox Code Playgroud)
但显然这不起作用,因为bind需要参数而不是参数数组.我知道我可以通过将我的回调插入到arguments数组的末尾并使用apply来做到这一点:
arguments[arguments.length] = function(err, docs) { ... }
db.find.apply(null, arguments);
Run Code Online (Sandbox Code Playgroud)
或者通过遍历arguments数组并为每个参数重新绑定函数:
var bound, context;
for(var i = 0; i < arguments.length; i++) {
context = bound ? bound : db.find;
bound = context.bind(null, arguments[i]);
}
bound(function(err, docs) { ... })
Run Code Online (Sandbox Code Playgroud)
但这两种方法都很脏.有任何想法吗?
javascript functional-programming partial-application promise
以python内置pow()函数为例.
xs = [1,2,3,4,5,6,7,8]
from functools import partial
list(map(partial(pow,2),xs))
>>> [2, 4, 8, 16, 32, 128, 256]
Run Code Online (Sandbox Code Playgroud)
但是我如何将xs提高到2的幂?
要得到 [1, 4, 9, 16, 25, 49, 64]
list(map(partial(pow,y=2),xs))
TypeError: pow() takes no keyword arguments
Run Code Online (Sandbox Code Playgroud)
我知道列表理解会更容易.
我注意到当我使用期望其他函数作为参数的函数时,我有时可以这样做:
someFunction(firstParam,anotherFunction)
Run Code Online (Sandbox Code Playgroud)
但其他时候,编译器给我一个错误,告诉我应该编写一个这样的函数,以便将它视为部分应用的函数:
someFunction(firstParam,anotherFunction _)
Run Code Online (Sandbox Code Playgroud)
例如,如果我有这个:
object Whatever {
def meth1(params:Array[Int]) = ...
def meth2(params:Array[Int]) = ...
}
import Whatever._
val callbacks = Array(meth1 _,meth2 _)
Run Code Online (Sandbox Code Playgroud)
为什么我不能拥有如下代码:
val callbacks = Array(meth1,meth2)
Run Code Online (Sandbox Code Playgroud)
在什么情况下编译器会告诉我添加_?
所以我想了解partial:
import functools
def f(x,y) :
print x+y
g0 = functools.partial( f, 3 )
g0(1)
4 # Works as expected
Run Code Online (Sandbox Code Playgroud)
在:
g1 = functools.partial( f, y=3 )
g1(1)
4 # Works as expected
Run Code Online (Sandbox Code Playgroud)
在:
g2 = functools.partial( f, x=3 )
g2(1)
TypeError: f() got multiple values for keyword argument 'x'
Run Code Online (Sandbox Code Playgroud)
TypeError如果我y用作关键字参数,则消失:
在:
g2( y=1 )
4
Run Code Online (Sandbox Code Playgroud)
是什么导致的TypeError?
在像Haskell这样的函数式编程中,我可以定义函数
add a b = a+b
Run Code Online (Sandbox Code Playgroud)
然后add 3将返回一个带有一个参数的函数并返回3 + something
我怎么能在GO中这样做?
当我定义一个多于一个(比如n)参数的函数时,我可以只给它一个参数并得到另一个带n-1个参数的函数吗?
更新:
对不起我原来问题中的不精确的话.
我认为我的问题应该被问为两个问题:
感谢TheOnly92和Alex解决我的第二个问题.但是,我对第一个问题也很好奇.
假设我在R中有一个带有多个参数的函数,我想通过将一些参数设置为预先指定的值来将其减少为参数较少的函数.我试图找出最好的方法是在R.
例如,假设我有一个功能
f <- function(a,b,c,d){a+b+c+d}
Run Code Online (Sandbox Code Playgroud)
我想创建或找到一个函数partial,它将执行以下操作
partial <- function(f, ...){
#fill in code here
}
new_f <- partial(f, a=1, c= 2)
Run Code Online (Sandbox Code Playgroud)
new_f将是一个功能b和d和将返回1+b+2+d
在python我会这样做
from functools import partial
def f(a,b,c,d):
return a+b+c+d
new_f = partial(f, a=1, c= 2)
Run Code Online (Sandbox Code Playgroud)
我实际上反复这样做,所以我需要尽可能高效.谁能指出我最有效的方法呢?现在我能做的最好的就是
partial <- function(f, ...){
z <- list(...)
formals(f) [names(z)] <- z
f
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以告诉我更快的方式或最好的方法吗?这太慢了.
在以下代码中:
ismaxl :: (Ord a) => [a] -> a -> Bool
ismaxl l x = x == maxel
where maxel = maximum l
main = do
let mylist = [1, 2, 3, 5]
let ismax = ismaxl mylist
--Is each call O(1)? Does each call remember maxel?
let c1 = ismax 1
let c2 = ismax 2
let c3 = ismax 3
let c5 = ismax 5
putStrLn (show [c1, c2, c3, c5])
Run Code Online (Sandbox Code Playgroud)
部分函数是否为max,计算maxel?特别是,有人可以指出关于Haskell中部分函数的复杂性的规则吗?在上面的例子中,编译器必须只调用一次最大值吗?换句话说,部分函数是否保留了内部where子句的先前调用的引用?
我有一些CPU限制的代码不能令人满意,我正在寻找可能的错误,我的理由是复杂性.
performance profiling haskell partial-application lazy-evaluation
在Douglas Crockford的书"Javascript:The Good Parts"中,他提供了一个curry方法的代码,该方法接受一个函数和参数,并使用已经添加的参数返回该函数(显然,这不是"咖喱"的意思,而是一个例子,"部分申请").这是我修改过的代码,以便在没有其他自定义代码的情况下工作:
Function.prototype.curry = function(){
var slice = Array.prototype.slice,
args = slice.apply(arguments),
that = this;
return function() {
// context set to null, which will cause `this` to refer to the window
return that.apply(null, args.concat(slice.apply(arguments)));
};
};
Run Code Online (Sandbox Code Playgroud)
所以如果你有一个add功能:
var add = function(num1, num2) {
return num1 + num2;
};
add(2, 4); // returns 6
Run Code Online (Sandbox Code Playgroud)
你可以创建一个已经有一个参数的新函数:
var add1 = add.curry(1);
add1(2); // returns 3
Run Code Online (Sandbox Code Playgroud)
这很好.但我想知道的是为什么他设置this到null?预期的行为是不是咖喱方法与原始方法相同,包括相同的this? …
在Python中,它被认为是更好的风格:
我将通过一个人为的例子来解释我的问题.
假设有人编写一个函数_sort_by_scoring,它接受两个参数:评分函数和项列表.它返回原始列表的副本,该副本按照每个项目在原始列表中的位置的分数排序.还提供了两个示例评分函数.
def _sort_by_score(scoring, items_list):
unsorted_scored_list = [(scoring(len(items_list), item_position), item) for item_position, item in enumerate(items_list)]
sorted_list = [item for score, item in sorted(unsorted_scored_list)]
return sorted_list
def _identity_scoring(items_list_size, item_position):
return item_position
def _reversed_scoring(items_list_size, item_position):
return items_list_size - item_position
Run Code Online (Sandbox Code Playgroud)
函数_sort_by_score永远不会直接调用; 相反,它由其他单参数函数调用,它将评分函数及其唯一参数(项目列表)传递给_sort_by_scoring并返回结果.
# Explicit function definition style
def identity_ordering(items_list):
return _sort_by_score(_identity_scoring, items_list)
def reversed_ordering(items_list):
return _sort_by_score(_reversed_scoring, items_list)
Run Code Online (Sandbox Code Playgroud)
显然,这个意图在函数currying方面表达得更好.
# Curried function definition style
import functools
identity_ordering = functools.partial(_sort_by_score, _identity_scoring)
reversed_ordering = functools.partial(_sort_by_score, _reversed_scoring)
Run Code Online (Sandbox Code Playgroud)
用法(在任何一种情况下):
>>> foo = [1, 2, …Run Code Online (Sandbox Code Playgroud)