由于Kotlin支持函数式编程的许多概念,我想知道是否有办法在Kotlin中部分应用函数?
部分应用程序可能有用的一个这样的例子是:
// In one class
fun doSomething(cb: (a, b) -> Unit) {
<some logic here to compute someField>
doSomethingElse(cb.applyPartially(someField))
}
// In another class
fun doSomethingElse(cb: (b) -> Unit) {
<some logic here to compute someOtherField>
cb(someOtherField)
}
Run Code Online (Sandbox Code Playgroud) 我试图了解有关 Haskell 函数的一些内容。
首先,这是一个以典型的“慢”方式定义的斐波那契函数(即没有记忆的递归,也没有无限列表技巧)
slowfib :: Int -> Integer
slowfib 0 = 0
slowfib 1 = 1
slowfib n = slowfib (n-2) + slowfib (n-1)
Run Code Online (Sandbox Code Playgroud)
接下来,相同的规范记忆版本。(仅与教程/书籍/等中的典型示例略有不同,因为我更喜欢!!运算符的前缀版本。)
memfib = (!!) (map fib [0..])
where
fib 0 = 0
fib 1 = 1
fib k = memfib(k-2) + memfib(k-1)
Run Code Online (Sandbox Code Playgroud)
上面的解决方案使用了!!运算符的部分应用,这是有道理的:我们希望memfib最终成为一个带参数的函数,并且我们正在定义它而不在定义中包含参数。
到现在为止还挺好。现在,我想我可以编写一个等效的记忆函数,在定义中包含一个参数,所以我这样做了:
memfib_wparam n = ((!!) (map fib [0..])) n
where
fib 0 = 0
fib 1 = 1
fib k = memfib_wparam(k-2) + memfib_wparam(k-1) …Run Code Online (Sandbox Code Playgroud) haskell functional-programming memoization partial-application fibonacci
我目前有一个部分应用程序功能,如下所示:
Function.prototype.curry = function()
{
var args = [];
for(var i = 0; i < arguments.length; ++i)
args.push(arguments[i]);
return function()
{
for(var i = 0; i < arguments.length; ++i)
args.push(arguments[i]);
this.apply(window, args);
}.bind(this);
}
Run Code Online (Sandbox Code Playgroud)
问题是它只适用于非成员函数,例如:
function foo(x, y)
{
alert(x + y);
}
var bar = foo.curry(1);
bar(2); // alerts "3"
Run Code Online (Sandbox Code Playgroud)
如何将咖喱函数重新应用于成员函数,如:
function Foo()
{
this.z = 0;
this.out = function(x, y)
{
alert(x + y + this.z);
}
}
var bar = new Foo;
bar.z = 3;
var foobar …Run Code Online (Sandbox Code Playgroud) 考虑一下:
scala> def sum(x:Int,y:Int) = x+y
sum: (x: Int, y: Int)Int
scala> sum(1,_:String)
<console>:9: error: type mismatch;
found : String
required: Int
sum(1,_:String)
Run Code Online (Sandbox Code Playgroud)
显然Scala非常了解_in 的确切类型,sum(1,_)但你必须这样做 say sum(1,_:Int).为什么?
Scala随机选择(?)选择一个:
scala> def sum(x:Int,y:String) = 1
sum: (x: Int, y: String)Int
scala> def sum(x:Int,y:Double) = 1
sum: (x: Int, y: Double)Int
scala> class Ashkan
defined class Ashkan
scala> sum(1,_:Ashkan)
<console>:10: error: type mismatch;
found : Ashkan
required: Double
sum(1,_:Ashkan)
Run Code Online (Sandbox Code Playgroud) 我有一个功能,我基本上从Clojure谷歌小组的讨论中拉出来,它采用一个集合和一个任意长度的函数列表,并过滤它以返回一个新的集合,其中包含至少一个原始列表的所有元素函数的计算结果为true:
(defn multi-any-filter [coll & funcs]
(filter #(some true? ((apply juxt funcs) %)) coll))
Run Code Online (Sandbox Code Playgroud)
我正在为Project Euler Problem 1制作一个可推广的解决方案,所以我正在使用它:
(def f3 (fn [x] (= 0 (mod x 3))))
(def f5 (fn [x] (= 0 (mod x 5))))
(reduce + (multi-any-filter (range 1 1000) f3 f5))
Run Code Online (Sandbox Code Playgroud)
这给出了正确的答案.
但是,我想修改它,所以我可以传递给它而不是函数,比如
(reduce + (multi-any-filter (range 1 1000) 3 5))
Run Code Online (Sandbox Code Playgroud)
我可以用任意数量的int替换3和5,并在multi-any-filter函数中作为匿名函数执行函数包装(= 0(mod xy)).
不幸的是,这超出了我的Clojure能力的极限.我想我需要对mapargs列表做一些事情,但我不知道如何map返回一个函数列表,每个函数都在等待另一个参数.Clojure似乎并不支持我学习如何在其他函数式语言中使用它的方式.也许我需要partial在正确的位置使用,但我不太确定如何.
换句话说,我希望能够传递任意数量的参数(不是函数),然后将每个参数包装在同一个函数中,然后将该函数列表传递给我的juxt代替以上功能.funcsmulti-any-filter
谢谢你的任何提示!
给定一些函数 f(x1,x2,x3,..,xN),在几个地方部分应用它通常很有用。例如,对于 N=3,我们可以定义 g(x)=f(1,x,3)。然而,Haskell 中的标准部分应用程序不是这样工作的,它只允许我们通过固定它的第一个参数来部分应用一个函数(因为所有函数实际上只接受一个参数)。有没有什么简单的方法可以做这样的事情:
g = f _ 2 _
g 1 3
Run Code Online (Sandbox Code Playgroud)
输出值f 1 2 3? 当然我们可以做一个 lambda 函数
g=(\x1 x3 -> f x1 2 x3)
Run Code Online (Sandbox Code Playgroud)
但我觉得这很不可读。例如,在 Mathematica 中,它是这样工作的,我觉得这很好:
g=f[#1,2,#2]&
g[1,3]
Run Code Online (Sandbox Code Playgroud)
与输出f[1,2,3]。
编辑:也许我应该多谈谈动机。我想在点式组合中使用这种部分应用的函数,即在这样的表达式中:
h = g. f _ 2 . k
Run Code Online (Sandbox Code Playgroud)
得到h 3 = g(f(k(3),2))。
我正在使用具有以下功能的ObserverAPI(ObserverSet):
public func add<T: AnyObject>(object: T, _ f: T -> Parameters -> Void) -> ObserverSetEntry<Parameters>
Run Code Online (Sandbox Code Playgroud)
它只是注册一个object然后调用实例方法f的object通知时,触发器
在我的一位经理中,我需要隐藏前一个函数,因此我可以强制观察者调用通过协议实现的预定义函数.
这是我到目前为止所做的:
@objc protocol Observer : NSObjectProtocol {
func observe(param: String) -> Void
}
func addObserver<T: AnyObject where T: Observer>(observer: T) {
let f: T -> String -> Void = observer.dynamicType.observe
entries.addObserver(observer, f)
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我出现以下错误 Partial application of generic method is not allowed
我在SO上找到了一个可能的解决方法,看起来像这样:
let f: T -> String -> Void = { (obs: …Run Code Online (Sandbox Code Playgroud) 取自typelevel/kind-projector,它们之间的区别是什么:
// partially-applied type named "IntOrA"
type IntOrA[A] = Either[Int, A]
Run Code Online (Sandbox Code Playgroud)
和
// type projection implementing the same type anonymously (without a name).
({type L[A] = Either[Int, A]})#L
Run Code Online (Sandbox Code Playgroud)
?
它们是等价的吗?
函数范围提供JavaScript中唯一的隐私.
所以规范:
function Ctor(dep1, dep2) {
this._dep1 = dep1;
this._dep2 = dep2;
}
Ctor.prototype.foo = function() {
// use this._dep1/2...
}
Run Code Online (Sandbox Code Playgroud)
...有问题的是它没有为注入的依赖项提供封装.
foo提供真正封装的替代方案(尽管在位置方面略有不同)可能是:
function factory(dep1, dep2) {
return {
foo: partial(foo, dep1, dep2), // or use bind (partial could be a library fn for partial application)
};
}
function foo(dep1, dep2) {
// use dep1/2
}
Run Code Online (Sandbox Code Playgroud)
但我很少看到这种模式.有没有充分的理由不使用后者?
考虑以下类型定义:
trait LiftF[F[_], G[_]] {
def liftF[A](fa: F[A]): G[A]
}
Run Code Online (Sandbox Code Playgroud)
在上下文边界中提供对此类隐式的要求时(使用种类投影仪插件),我们必须这样编写:
def func[A, G[_], F[_]: LiftF[?[_], G]](a: F[A]): G[A]
Run Code Online (Sandbox Code Playgroud)
我想摆脱这一?[_]部分,所以我最初的猜测是编写一个To[G[_]]返回的类型,LiftF[?[_], G]以将上述函数定义转换为
def func[A, G[_], F[_]: LiftF.To[G]](a: F[A]): G[A]
Run Code Online (Sandbox Code Playgroud)
但是,在将类型To定义写为
type To[G[_]] = LiftF[?[_], G]
Run Code Online (Sandbox Code Playgroud)
我收到以下编译错误:
Error:(17, 20) type ?$ takes type parameters
type To[G[_]] = LiftF[?[_], G]
Run Code Online (Sandbox Code Playgroud)
尝试使用存在性类型重写它会产生以下类型定义:
type To[G[_]] = LiftF[F, G] forSome { type F[X] }
Run Code Online (Sandbox Code Playgroud)
这可以很好地编译,但是,毫无疑问,它不能应用于其他类型参数,因此无法实现所需的函数定义。
我设法通过受aux模式启发的代码实现了“部分应用程序”部分:
trait To[G[_]] {
type From[F[_]] = LiftF[F, G]
}
Run Code Online (Sandbox Code Playgroud)
可悲的是,这给我留下了比原始语法差的语法:
def func[A, …Run Code Online (Sandbox Code Playgroud) types scala partial-application higher-kinded-types kind-projector