Swift 中的 Curry 函数 [英] Curry Function in Swift

查看:37
本文介绍了Swift 中的 Curry 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想制作一个返回咖喱函数的函数,如下所示

I want to make a function that return a curry function like below

func addTwoNumbers(a: Int)(b: Int) -> Int {
    return a + b
}

addTwoNumbers(4)(b: 6) // Result: 10

var add4 = addTwoNumbers(4)
add4(b: 10) // returns 14     

这种函数的返回类型是什么,我如何使用带有可变参数的函数来生成这样的函数.

What is the return type of such function and how can I generate a function like this using a function that take Variadic parameters.

func generateCurry(.../*Variadic parameters*/) -> .../*curry function type*/ {
  return ...//curry function
}

我想要一个通用的解决方案,而不是只将 Int 作为 generateCurry 函数参数中的参数

I want a generic solution and not take only Int as arguments in the parmeter of the generateCurry function

let curried = curry(func(a, b, c) {
  print(a + b + c)
})
curried(1)(2)(3) //prints 6

推荐答案

你可以用闭包很容易地做到这一点:

You can achieve this pretty easily with closures:

/// Takes a binary function and returns a curried version
func curry<A,B,C>(f: (A, B) -> C) -> A -> B -> C {
    return { a in { b in f(a, b) } }
}

curry(+)(5)(6) // => 11

let add: Int -> Int -> Int = curry(+)
add(5)(6) // => 11

能够对带有 3、4 或更多参数的函数做同样的事情,但不重复实现,这真是太好了.此类函数的签名可能类似于:

It would be really nice to be able to do the same thing for functions that take 3, 4 or more arguments, but without duplicating the implementation. The signature of such a function might start something like:

/// Take a function accepting N arguments and return a curried version
func curry<T>(args: T...) -> /* ? */

返回类型是什么?它会根据函数的输入而改变.目前这在 Swift 中绝对是不可能的,我认为如果没有某种宏系统,这根本不可能.但即使使用宏,我也不认为编译器会满意,除非它在编译时知道列表的长度.

What would the return type be? It would change based on the input to the function. This definitely isn't possible in Swift at the moment, and I don't think it would be possible at all without some kind of macro system. But even with macros I don't think the compiler would be satisfied unless it knew the length of the list at compile-time.

话虽如此,使用接受 3、4、5 或更多参数的版本手动重载柯里化函数真的很简单:

Having said that, it's really straight-forward to manually overload the currying function with a version that accepts 3, 4, 5 or more parameters:

func curry<A,B,C,D>(f: (A, B, C) -> D) -> A -> B -> C -> D {
    return { a in { b in { c in f(a,b,c) } } }
}

func curry<A,B,C,D,E>(f: (A, B, C, D) -> E) -> A -> B -> C -> D -> E {
    return { a in { b in { c in { d in f(a,b,c,d) } } } }
}

// etc.

这篇关于Swift 中的 Curry 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆