Curried Closures in Swift - swift

In swift we can define a function like this:
func format(name: String)(email: String) -> String {
return "\(name)-\(email)"
}
I want to define a closure that is curried like that function. But compiler gives me error. Here is my curried closure looks like this:
let formatClosure = {(name: String)(email: String) -> String in "\(name)-\(email)"}
Is this simply impossible in swift or is there some other syntax for it?

It looks like there concise version available to straight functions doesn't work for closures. You can still do it using a slightly expanded syntax though.
let formatClosure = {(name: String) -> String -> String in { email in "\(name)-\(email)" } }

Related

Swift: Closure with receiver like kotlin equivalent?

Hello I would like to know if there is the equivalent of kotlin lambda with receiver, in swift?
Like this:
fun <T> T.apply(block: T.() -> Unit): T
The T.() there is equivalent of this practice in swift?
I'm not familiar with Kotlin's lambda with receiver, but as far as I read Kotlin docs,
There's no direct equivalent in Swift
Same functionality can be achieved by adding a parameter or currying
But, in Swift, you cannot define an extension function on generic T where T is any type. So, something like your T.apply needs to be a global function with two arguments.
With currying, apply in Swift would be something like this:
func apply<T>(_ this: T, block: (T)->()->T) -> T {
return block(this)()
}
You can use it like this:
var result = apply("Abc") {this in {this.uppercased()+this.lowercased()}}
print(result) //->ABCabc

Swift Cast to Generic Type with Constraint

I am using Swift 3 with constrained generics (i.e. a where clause). I have a problem when I am trying to do generic type casting. Here is a simplified example of the problem:
func jsonToObj<T:DomainResource>(jsonStr: String) -> [T:DomainResource] {
let json = JSON(parseJSON: jsonStr).dictionaryObject
let bundle = SMART.Bundle(json: json)
let result = bundle.entry?.map() {
return $0.resource as! T
}
return result!
}
My problem is when I return from the method, the compiler complains its cannot convert type [T] to type [T:DomainResource]. If I remove the DomainResource constraint from the generic, it compiles and runs just fine.
That's not what I want, so, I tried this:
let result = bundle.entry?.map() {
return $0.resource as! T:DomainResource
}
Swift doesn't seem to know what that means. Any idea on how to work around this problem? I'd like to not just cast them all to DomainResource objects, if possible.
You wrote this function signature:
func jsonToObj<T:DomainResource>(jsonStr: String) -> [T:DomainResource]
This says that the jsonToObj(jsonStr:) method returns a dictionary whose keys are of type T and whose values are of type DomainResource. It looks like you just want to write this function signature:
func jsonToObj<T:DomainResource>(jsonStr: String) -> [T]

Adding vars to a closure swift

hey I'm a little confused about block syntax. I currently have a function defined like so:
func presentRateAlert(ID: Int, didDismiss: (() -> Void)?)
Currently I do not have any parameters in the block, but I would like to include two. rating: Double? and message: String?. How would I include these?
In your function declaration, didDismiss is a closure. It's type is (() -> Void)?), which is an Optional closure that takes no parameters, and returns Void (no result.)
If you change it to (() -> (Double,String)?
Then your closure returns a Tuple which contains a Double and a String.
(In Swift a function can only return one result. Normally you make that result a Tuple when you want to return more than one thing.)
EDIT:
Based on your edits, it seems you want to add PARAMETERS to your closure, not a return value as you said originally.
An Optional closure that takes a Double and a String and does not return a value would be declared as ((Double, String) -> Void)?)
A function that takes such a closure might look like this:
func test(id: Int, closure: ((Double, String) -> Void)?) {
closure?(3.14, "pi")
}
And calling it might look like this:
test(id: 6, closure: {
(aDouble, aString) in
print("In closure, double = \(aDouble), string = \(aString)")
})

Using overloaded functions as first class citizens

Suppose that we have several overloaded functions in one class:
func appendToABC(string s: String) -> String {
return "ABC \(s)"
}
func appendToABC(duplicatedString s: String) -> String {
return "ABC \(s)\(s)"
}
And we have some API that gets function as an argument:
func printString(function: (String) -> String) {
print(function("ASD"))
}
How can we pass one of appendToABC functions as an argument to a printString function?
I've thought about wrapping the function with a closure, but it doesn't look nice
printString { appendToABC(duplicatedString: $0) }
This is a known limitation in Swift. There is an open proposal to address it. Currently the only solution is a closure.
Note that this is true of many things in Swift. You also can't refer to properties directly as functions, even though they behave like functions. You must use a closure. And even some free functions cannot be directly passed (print is the most common example).

Swift: Benefits of Curry Function

I'm trying to grasp the concept behind curry functions. Below is the code:
class MyHelloWorldClass {
func helloWithName(name: String) -> String {
return "hello, \(name)"
}
}
I can create a variable that points to the class’s helloWithName function:
let helloWithNameFunc = MyHelloWorldClass.helloWithName
// MyHelloWorldClass -> (String) -> String
My new helloWithNameFunc is of type MyHelloWorldClass -> (String) -> String, a function that takes in an instance of my class and returns another function that takes in a string value and returns a string value.
So I can actually call my function like this:
let myHelloWorldClassInstance = MyHelloWorldClass()
helloWithNameFunc(myHelloWorldClassInstance)("Mr. Roboto")
// hello, Mr. Roboto
Credit: I go this code from this site
What is the benefit of using the above curry function? When would there a need to call a function that takes an instance of its class, that takes the subsequent parameter that was passed.
The problem is that the example given isn't an example of currying exactly. That's why you don't see any value in it.
This is a better example of currying:
class MyHelloWorldClass {
//Function that takes two arguments
func concatenateStrings(string1: String, string2: String) {
return "\(string1)\(string2)"
}
//Curried version of concatenateStrings that takes one argument.
func helloWithName(name: String) -> String {
return concatenateStrings("hello, ", name)
}
}
This is a better example of how function variables are curried functions in Swift: http://oleb.net/blog/2014/07/swift-instance-methods-curried-functions/