Given this simple currying function:
func foo(x:Int)(y:Int)->String{
return "\(x) with \(y)"
}
I'd expect to be able to do something like this:
let bar = foo(1)
bar(2) //<- error: Missing argument label 'y:' in call
If I label the call to bar (as in bar(y:2)) everything works fine. But I don't understand why the parameter name is necessary. Is there any way to avoid it?
The obvious thing:
func foo(x:Int)(_ y:Int)->String ...
does not seem to work.
It's a bug, you should file a radar at bugreport.apple.com
As a confirmation, if you place an underscore, like this
func foo(x: Int)(_ y: Int) -> String
you get a warning
Extraneous '_' in parameter: 'y' has no keyword argument name
So it explicitly says that y has no external name, but it still requires one when called, which is clearly against the language specification.
I believe it is a compiler bug, your example should work as described in The Swift Programming Language book where they mention declaring curried functions:
func addTwoNumbers(a: Int)(b: Int) -> Int {
return a + b
}
addTwoNumbers(4)(5) // Returns 9
https://bugreport.apple.com
good find!
I am not sure I fully understand your currying. Here is my take on it. I have a function foo as follows:
func foo(x:Int, y:Int) -> String{
return "\(x) with \(y)"
}
let bar = foo(1, 2) // gives "1 with 2"
I wish to curry this function to 'fix' the value for x, so do so as follows:
func fooCurry(x:Int) -> (Int -> String) {
func curry(y:Int) -> String {
return foo(x, y)
}
return curry
}
The above returns a new function which can be used as follows:
let curriedFoo = fooCurry(1)
let barWithCurry = curriedFoo(2) // gives "1 with 2"
The function returned by fooCurry has the signature (Int -> String), which means that the parameter does not have an external name.
Not the best syntax, but if you want to get around it for now, you can use the following for basic curried functions:
func foo(x:Int) -> Int -> String {
return {
return "\(x) with \($0)"
}
}
Then you can just do:
let bar = foo(1)
bar(2) //-> 1 with 2
Now obviously the problem with this becomes obvious when you want to write a curried function for piping four Ints for example:
func makerAdders(a:Int)(b:Int)(c:Int)(d:Int) {...}
becomes like this:
func add(a:Int) -> Int -> Int -> Int -> Int {
return {
b in return {
c in return {
d in return a + b + c + d
}
}
}
}
The inner closures make it a bit better than using inner functions, but again it defeats the purpose of the nice func add(a:Int)(b:Int)(c:Int)(d:Int) {return a+b+c+d} syntax.
Definitely a bug in the compiler as far as I can tell. Until it's fixed you can get a properly curried version of any function using these functions (note that I've included cases for two and three arguments, extend at your leisure:
func curry<A,B,C>(f: (A, B) -> C) -> A -> B -> C {
return { a in { b in return f(a,b) } }
}
func curry<A,B,C,D>(f: (A, B, C) -> D) -> A -> B -> C -> D {
return { a in { b in { c in return f(a,b,c) } } }
}
Just use:
curry(addTwoNumbers)(1)(2)
Related
Swift 3 has introduced the #discardableResult annotation for functions to disable the warnings for an unused function return value.
I'm looking for a way to silence this warning for closures.
Currently, my code looks like this:
func f(x: Int) -> Int -> Int {
func g(_ y: Int) -> Int {
doSomething(with: x, and: y)
return x*y
}
return g
}
In various places I call f once to obtain a closure g which I then call repeatedly:
let g = f(5)
g(3)
g(7)
g(11)
In most places I'm only interested in the side effects of the nested call to doSomething, and not in the return value of the closure g. With Swift 3, there are now dozens of warnings in my project for the unused result. Is there a way to suppress the warnings besides changing the calls to g to _ = g(...) everywhere? I couldn't find a place where I could place the #discardableResult annotation.
I don't think there's a way to apply that attribute to a closure. You could capture your closure in another that discards the result:
func discardingResult<T, U>(_ f: #escaping (T) -> U) -> (T) -> Void {
return { x in _ = f(x) }
}
let g = f(5)
g(3) // warns
let h = discardingResult(g)
h(4) // doesn't warn
I was looking for an answer to this recently, and I've found another way (a newer way) to do this!
It could arguably be overkill for some simple problems, but I just thought that this is an interesting yet neat approach that's worth sharing.
Say you have a closure that doubles an integer value:
let double = { (int: Int) -> Int in
return int * 2
}
With Swift 5.0 (SE-0216) introducing the #dynamicCallable attribute, you can "wrap" your closure with #discardableResult by creating a dynamically callable class or struct as such:
// same for struct, except without the need of an initializer
#dynamicCallable
class DiscardableResultClosure<T, U> {
var closure: (T) -> U
#discardableResult
func dynamicallyCall(withArguments args: [Any]) -> U {
let arg = args.first as! T
return self.closure(arg)
}
// implicit for struct
init(closure: #escaping (T) -> U) {
self.closure = closure
}
}
double(5) // warning: result of call to function returning 'Int' is unused
let discardableDouble = DiscardableResultClosure(closure: double)
discardableDouble(5) // * no warning *
Even better, in Swift 5.2 (SE-0253), you can create a dynamically callable struct using a built-in callAsFunction method without going through the trouble of using the attribute #dynamicCallable (or using class) with its sometimes cumbersome declaration.
struct DiscardableResultClosure<T, U> {
var closure: (T) -> U
#discardableResult
func callAsFunction(_ arg: T) -> U {
return closure(arg)
}
}
let discardableDouble = DiscardableResultClosure(closure: double)
discardableDouble(5) // * no warning *
Is it possible to call a function as a parameter of another function in Swift??
I am making a sound effects app in Swift which uses different effects like AVAudioUnitReverb() and AVAudioUnitDistortion() etc. I wanted to create a single function and just be able to call which effects I wanted to do.
Because in Swift functions are first-class types, you can pass it as an argument to another function.
Example:
func testA() {
print("Test A")
}
func testB(function: () -> Void) {
function()
}
testB(testA)
You can pass in functions as parameter my typing the parameter with the same signature.
As sunshine's example just deals with Void parameters and return types, I want to add another example
func plus(x:Int, y:Int) -> Int {
return x + y
}
func minus(x:Int, y:Int) -> Int {
return x - y
}
func performOperation (x:Int, _ y:Int, op:(x:Int,y: Int) -> Int) -> Int {
return op(x: x, y: y)
}
let resultplus = performOperation(1, 2, op: plus) // -> 3
let resultminus = performOperation(1, 2, op: minus) // -> -1
note: Of course you should consider dynamic typed parameters. For simplicity here just Ints
this is called Higher Order Functions and in many languages this is the way of doing it. But often you don't won't to explicitly create functionss for it. Here Closures are a perfect tool:
The function performOperation stays untouched, but the operations are implemented differently:
let plus = { (x:Int, y:Int) -> Int in
return x + y
}
let minus = { (x:Int, y:Int) -> Int in
return x - y
}
let resultplus = performOperation(1, 2, op: plus)
let resultminus = performOperation(1, 2, op: minus)
Often this would be preferred as it doesn't need methods to be added to a class, pretty much like anonymous functions in other languages.
More on this and how it is used in the swift standard library: https://www.weheartswift.com/higher-order-functions-map-filter-reduce-and-more/
I would recommend book "IOS 9 Programming Fundamentals with Swift" by Matt Neuburg, especially subchapter "Functions".
You should not only find the answer for your question:
func imageOfSize(size:CGSize, _ whatToDraw:() -> ()) -> UIImage {
...
}
But also how to construct function that returns the function:
func makeRoundedRectangleMaker(sz:CGSize) -> () -> UIImage {
...
}
As well as brief introduction to Curried Functions.
I'm new to Swift, and when I look the book, I found the currying in Swift is complicated, and I write the code follow the book, such as:
func curry<A, B, C>(f: (A, B) -> C) -> A -> B -> C {
return { x in { y in f(x, y) } }
}
func paraFunc(pa: Int, pb: Int) -> Int {
return pa - pb
}
var cab = curry(paraFunc)
cab(2)(3)
and I don't know how to comprehend the "-> A -> B -> C". And I know the Generics. But I confused about the func curry, how it works? and anybody can help me?
-> operator is right associative. So we can rewrite curry function like this.
func curry<A, B, C>(f: #escaping (A, B) -> C) -> ((A) -> ((B) -> C)) {
return { x in { y in f(x, y) } }
}
Every ( matches with { inside return part.
EDIT: Further explanation
curry function takes a non-curried two argument function and makes it curried. For example we have:
func sum(a: Int, b: Int) -> Int {
return a + b
}
Now we can use this function like this:
let result = sum(3, 6)
But if we make it curried
let curriedSum = curry(sum)
Now we can use it like this:
let result = curriedSum(3)(6)
At first this seems unnecessary and complex. But think about what next expression does.
let sumWith3 = curriedSum(3)
This produces a new function that takes an Int sums it with 3. Now here we created a new function from another function. Now we can use it like any other function.
Currying is common paradigm in functional programming. In fact in Haskell (another functional programming language) every function is curried by default.
As an exercise, I'm trying to extend Array in Swift to add a sum() member function. This should be type safe in a way that I want a call to sum() to compile only if the array holds elements that can be added up.
I tried a few variants of something like this:
extension Array {
func sum<U : _IntegerArithmeticType where U == T>() -> Int {
var acc = 0
for elem in self {
acc += elem as Int
}
return acc
}
}
The idea was to say, “OK, this is a generic function, the generic type must be something like an Int, and must also be the same as T, the type of the elements of the array”. But the compiler complains: “Same-type requirement make generic parameters U and T equivalent”. That's right, and they should be, with the additional contraint T : _IntegerArithmeticType.
Why isn't the compiler letting me do this? How can I do it?
(I know that I should later fix how things are added up and what the return type exactly is, but I'm stuck at the type constraint for now.)
As per Martin R's comment, this is not currently possible. The thing I'm tempted to use in this particular situation would be an explicit passing of a T -> Int conversion function:
extension Array {
func sum(toInt: T -> Int?) -> Int {
var acc = 0
for elem in self {
if let i = toInt(elem) {
acc += i
}
}
return acc
}
}
Then I can write stuff like this:
func itself<T>(t: T) -> T {
return t
}
let ss = ["1", "2", "3", "4", "five"].sum { $0.toInt() }
let si = [1, 2, 3, 4].sum(itself)
An explicit function has to be passed, though. The (itself) part can of course be replaced by { $0 }. (Others have called the itself function identity.)
Note that an A -> B function can be passed when A -> B? is needed.
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
}
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
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...) -> /* ? */
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.
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.
I'm not sure this is actually going to be possible in the same way it is inside of languages like Python.
The core problem I see to having a single generic solution is the strong typing of the closures/funcs you want to accept.
You could fairly easily create a curry function that worked on a specific or common function signature, but as far as a general purpose curry I don't see a way for it to work. The issue is more than about the types of the arguments (as mentioned in comments) but also with the number of them.
I've written up a simple example of how you could implement a curry function. It works, but I don't see a sane way to have a truly generic one like you can in more loosely typed languages.
func add(a1: Int, a2: Int) -> Int {
return a1 + a2
}
func curry(argument: Int, block: (Int, Int) -> Int) -> Int -> Int{
func curried(arg: Int) -> Int {
return block(argument, arg)
}
return curried
}
curry(5, add)(6)
In case you want to quickly get the curry function for any number of parameters, it's possible to generate it as shown in this gist.
The code is in Swift 2.2 and generates code for Swift 2.2 (at the moment). It uses simple template-based approach (a possible alternative is constructing an AST followed by code-generation):
func genCurry(n: Int, indent: Indent = .fourSpaces, accessLevel: AccessLevel = .Default, verbose: Bool = false) -> String {
// ...
// The bulky park is skipped for clarity.
return accessLevel.asPrefix + "func curry<\(genericParams)>(f: \(fSig)) -> \(curriedSig(n)) {\n"
+ indent.single + "return \(closure)\n"
+ "}\n"
}
I recently found that currying was removed back in Swift3. I created my own version which is repetitive but does the job.
precedencegroup CurryPrecedence {
associativity: left
higherThan: MultiplicationPrecedence
}
infix operator <<== :CurryPrecedence
//1 param
func <<==<A,Z>(_ f: #escaping (A) -> (Z), _ p:A) -> () -> (Z) {
{ f(p) }
}
//2 param
func <<==<A,B,Z>(_ f: #escaping (A, B) -> (Z), _ p:B) -> (A) -> (Z) {
{ (A) in f(A,p) }
}
//3 param
func <<==<A,B,C,Z>(_ f: #escaping (A, B, C) -> (Z), _ p:C) -> (A, B) -> (Z) {
{ (A, B) in f(A,B,p) }
}
//4 param
func <<==<A,B,C,D,Z>(_ f: #escaping (A, B, C, D) -> (Z), _ p:D) -> (A, B, C) -> (Z) {
{ (A, B, C) in f(A,B,C,p) }
}
To use it:
let ten = (addTwoNumbers <<== 6 <<== 4)()
or
let ten = (addTwoNumbers <<== 6)(4)