结合两个不同的函数定义——一个是咖喱,一个是标准

时间:2022-03-01 15:48:48

Been playing around with curried functions in swift, and I'm trying to write a function now that can be written as:

我一直在使用swift的curry过的函数,现在我正在尝试编写一个可以写成:

sum(1,2) //or
sum(1)(2) //both equal 3

This is easy to do with two function definitions:

这很容易做到两个函数定义:

// curried - usage: sum(1)(2) or sum(1)
func sum(a: Int) -> (Int -> Int) {
    return { b in a + b }
}

// regular - usage: sum(1,2)
func sum(a: Int, _ b: Int) -> Int {
    return a + b
}

I've been trying to combine these into one function that could be called either way, but I think I'm either stumped or there's no solution. I tried reworking it with generic types, but still ran into the problem of the number of parameters, even with optionals.

我一直在尝试把它们组合成一个函数,可以用任何一种方法来调用,但我想我要么是被难住了,要么是没有办法。我尝试用泛型类型重新处理它,但仍然遇到了参数数量的问题,即使是选项。

So, any ideas on how to combine these, or is it not possible with swift?

那么,关于如何组合这些东西的想法,或者是不可能与斯威夫特?

3 个解决方案

#1


1  

I have no idea why you are trying to do this, so I may have missed the point entirely, but this is the closest I can get to it...

我不知道你为什么要这么做,所以我可能完全没有抓住要点,但这是我能做到的最接近的……

enum IntOrFunction {
    case Number(Int)
    case Function((Int -> Int))
    var function: (Int -> Int) {
        switch self {
        case .Function(let f):
            return f
        case .Number(let i):
            return { _ in return i }
        }
    }
}

func sum(params: Int...) -> IntOrFunction {
    if params.count == 1 {
        let a = params[0]
        return .Function({ b in a + b })
    } else {
        return .Number(params.reduce(0, combine: {$0 + $1}))
    }
}

let a = sum(1,2) // "Number(3)"
let b = sum(1) // "Function((Function))"
let c = b.function(3) // "4"

#2


1  

Currying is a method of translating function with multiple parameters into sequence of function. So no, there is no way to do that. Only thing you can do is to create "interface"

Currying是一种将多个参数转换为函数序列的方法。不,没有办法这么做。你唯一能做的就是创建“接口”

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

func sum(a: Int, _ b: Int) -> Int {
    return sum(a)(b)
}

#3


0  

Maybe you can use something like this:

也许你可以这样使用:

func *<A, B, C>(lhs: A -> B -> C, rhs: (A, B)) -> C {
    return lhs(rhs.0)(rhs.1)
}

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

sum(1)(2)
sum*(1, 2)

#1


1  

I have no idea why you are trying to do this, so I may have missed the point entirely, but this is the closest I can get to it...

我不知道你为什么要这么做,所以我可能完全没有抓住要点,但这是我能做到的最接近的……

enum IntOrFunction {
    case Number(Int)
    case Function((Int -> Int))
    var function: (Int -> Int) {
        switch self {
        case .Function(let f):
            return f
        case .Number(let i):
            return { _ in return i }
        }
    }
}

func sum(params: Int...) -> IntOrFunction {
    if params.count == 1 {
        let a = params[0]
        return .Function({ b in a + b })
    } else {
        return .Number(params.reduce(0, combine: {$0 + $1}))
    }
}

let a = sum(1,2) // "Number(3)"
let b = sum(1) // "Function((Function))"
let c = b.function(3) // "4"

#2


1  

Currying is a method of translating function with multiple parameters into sequence of function. So no, there is no way to do that. Only thing you can do is to create "interface"

Currying是一种将多个参数转换为函数序列的方法。不,没有办法这么做。你唯一能做的就是创建“接口”

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

func sum(a: Int, _ b: Int) -> Int {
    return sum(a)(b)
}

#3


0  

Maybe you can use something like this:

也许你可以这样使用:

func *<A, B, C>(lhs: A -> B -> C, rhs: (A, B)) -> C {
    return lhs(rhs.0)(rhs.1)
}

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

sum(1)(2)
sum*(1, 2)