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/
Related
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)")
})
I am attempting to create a function that can return any type. I do not want it to return an object of type Any, but of other types, i.e. String, Bool, Int, etc. You get the idea.
You can easily do this using generics in this fashion:
func example<T>(_ arg: T) -> T {
// Stuff here
}
But is it possible to do it without passing in any arguments of the same type? Here is what I am thinking of:
func example<T>() -> T {
// Stuff here
}
When I try to do this, everything works until I call the function, then I get this error:
generic parameter 'T' could not be inferred
is it possible to do it without passing in any arguments of the same type?
The answer is yes, but there needs to be a way for the compiler to infer the correct version of the generic function. If it knows what it is assigning the result to, it will work. So for instance, you could explicitly type a let or var declaration. The below works in a playground on Swift 3.
protocol Fooable
{
init()
}
extension Int: Fooable {}
extension String: Fooable {}
func foo<T: Fooable>() -> T
{
return T()
}
let x: String = foo() // x is assigned the empty string
let y: Int = foo() // y is assigned 0
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).
The following code isn't compiling, though it seems to me it should:
public typealias ACallback = (first: [Int], second: String, third: String, fourth: CustomType) -> [Int];
public func doSomething(callback: ACallback = { $0 } {
...
}
I get an error on the function declaration's line:
'(first: [Int], second: String, third: String, fourth: CustomType)' is not convertible to '[Int]'
When I declare the function like so, it works:
public fund doSomething(callback: ACallback = { first, _, _, _ in first } {
It also makes no difference if I replace the ACallback with the same definition inline.
callback: ACallback = { $0.0 } should be OK, I think. As the error describes, $0 means a tuple of entire parameter list of that closure here.
Although the question isn't a duplicate—the answer to this question seems to explain this behaviour.
To answer the question in your comment—you could redefine the type as a structure or a class (whatever is suitable) and be able to refer to the arguments as properties (instead of as position numbers in the tuple).
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)" } }