Swift How to access parameter in function - swift

I have something like this:
enum Op {
case Operation(String, (Double, Double) -> Double)
}
Now I want to do this:
var description: String {
get {
switch Op {
case .Operation(let symbol, /* how can I access the two (Double, Double) from (Double, Double) -> Double? */ ):
return Double1 + symbol + Double2
}
}
}

Your question:
how can I access the two (Double, Double)
...makes no sense. There are no Doubles to access. The second value is a (Double, Double) -> Double. That's a function. Not a called function; just a function. The terms Double denote types, not values.
You could capture this function. You could call this function, yourself. But there are no Doubles there. Do you see?
Here's an example of actual working code; try it in a playground:
enum Op {
case Operation(String, (Double, Double) -> Double)
}
func f (x:Double, y:Double) -> Double { return x + y }
let op = Op.Operation("howdy", f)
switch op {
case .Operation(let symbol, let function) :
print(symbol) // Howdy
print(function(1,2)) // 3
}
Do you see? I didn't fetch the two Doubles; I supplied them.

Related

Swift: Determine the type of this constant

What is exactly the type of this const (val)?
let val = { (a: Int, b:Int)->Int in a + b }(1 , 2)
Isn't it (Int,Int) -> Int ?
It is just Int, because it takes only the final result, you call a function there that takes 2 Ints and return their adding result, which is going to be 3
In order to determine the type of a variable in the future you could just hold option key on the keyboard and hover over the variable name
There's already a good answer here, but I'd like to provide some more details for the records.
The following is a closure expression of type (Int, Int)->Int:
{ (a: Int, b:Int)->Int in a + b }
You could as well have defined an equivalent named function:
func f (_ a: Int, _ b:Int)->Int { a+b }
You could then have called the function with two parameters to get an Int value:
let val = f(1,2)
And you can do the same thing by replacing the function name with a closure expression:
let val = { (a: Int, b:Int)->Int in a + b }(1 , 2)
You could even combine the two practice and display step by step the type:
let l = { (a: Int, b:Int)->Int in a + b } // name the closure using a variable
print (type(of: l)) // (Int, Int)->Int
let val = l(1 , 2) // use the closure
print (type(of: val)) // Int
print (val)

Distinguishing Tuple and Multi-Argument Functions

I write this function in playground which has value parameter of tuple type and return type is tuple.
func tuple(value: (Int, Int) ) -> (first: Int, second: Int) {
let firstGrabTuple = value.0 + 5
let secondGrabTuple = value.1 + 5
return (firstGrabTuple, secondGrabTuple)
}
Then I assigned it to constant called closure
let closure = tuple
//(Playground showing) let closure became a function of type (Int, Int) -> (first: Int, second: Int)
Then for double check I write another function that takes closure as its parameter, of type ((Int, Int)) -> (Int, Int)
func anotherTuple(_ closure: ((Int, Int)) -> (Int, Int)) {
closure((5, 5))
}
when I call anotherTuple
anotherTuple { (x) -> (Int, Int) in
let first = x.0 + 5
let second = x.1 + 5
return (first, second)
}
//prints .0 10, .1 10 as expected
So My question is as mention above when first function tuple I assigned it to constant called closure became of type (Int, Int) -> (first: Int, second: Int). But in second function If i have to use a parameter of type as tuple I have to set its parameter in double parentheses like (_ closure: ((Int, Int)) -> (Int, Int)).
But If I remove those double parentheses from anotherTuple function parameter then it will only expect 2 values as multi-argument function. No error for used as multi-argument function instead of tuple argument why is that? Added image for more detail.
and second question is why that
let closure = tuple
//let closure became a function of type (Int, Int) -> (first: Int, second: Int)
not became of type ((Int, Int)) -> (first: Int, second: Int)
**Note - When I tried to pass that constant named closure as argument to another function which will expect closure of type ((Int, Int)) -> (Int, Int) then while typing closure showing me it as ((Int, Int)) -> (Int, Int) in auto complete code.
You're correct about the confusion. I'm somewhat going to just restate your understanding, and say "yes, tuples in Swift are weird and slightly broken."
Swift does not distinguish between functions that take tuples vs multiple arguments in some ways, but does distinguish in other ways. (This is one of many reasons to avoid tuples at this point in Swift's life.)
First, these two functions have almost the same type in Swift (note that Void and () are identical):
func tuple(value: (Int, Int) ) {} // (Int, Int) -> Void
func two(value1: Int, value2: Int) {} // (Int, Int) -> Void
They look the same. But if you define a function that accepts that type, it can't take tuple:
func take(f: (Int, Int) -> Void) {}
take(f: tuple) // Fails
take(f: two) // ok
But if you define a function that takes ((Int, Int)) -> Void it can accept either function:
func take(f: ((Int, Int)) -> Void) {}
take(f: tuple) // ok
take(f: two) // ok
That suggests that (Int, Int) -> Void is a subtype of ((Int, Int)) -> Void.
But variables belie this:
var f: (Int, Int) -> Void
f = tuple // Ok
f = two // Ok
var g: ((Int, Int)) -> Void
g = tuple // ok
g = two // ok
g = f // ok
f = g // ok
And that suggests that (Int, Int) -> Void and ((Int, Int)) -> Void are the same type. But the take function indicates they're not.
Yes. All of that is true at the same time. Functions that accept tuples are not a coherent type in Swift (they do not occupy a clearly-deliniated spot in the type hierarchy). That's just where we are in Swift today.
Old, incorrect answer.
This is just a quirk of Playgrounds, and you should feel free to open a radar about that.
If you check type(of: closure), it'll print the type you expect. Swift knows the correct type; Playgrounds just displays the wrong thing.

Swift: How do I pass in a value for this argument?

rk4_func(
y_array: [Double],
f_array: [(([Double], Double) -> Double)],
t_val: Double,
h_val: Double)
-> [Double]
I don't understand how to use the argument f_array: [(([Double], Double) -> Double)]. How exactly do I pass that in when calling the function?
That's kind of tricky :)
A quick remainder about Swift's function types: a type of (Int) -> Float means: a function that takes an int and returns a float. Okay, now back to your question:
As the argument f_array says (or, at least, tries to), it expects an array of functions. Inside this array, each function then accepts two arguments:
a doubles array: [Double]
a single double: Double
and returns a Double.
A quick example to get you going:
func f(_ a: [Double], _ b: Double) -> Double { ... }
func g(_ a: [Double], _ b: Double) -> Double { ... }
let f_array = [f, g]
There's a fair share of Swift magic up there. Please let me know if you need any further clarification.

swift calculator operation in a switch case

i am new in programming swift.i have made this code by following other tutorials but i canĀ“t find the correct write typ to perform operation?
#IBAction func operation(_ sender: UIButton) {
let operate = sender.currentTitle!
switch operate {
case "+" : performOperation() {}
case "-" : performOperation() {}
case "*" : performOperation() {}
case "/" : performOperation() {}
default: break
}
}
func performOperation(operate: (Double, Double) -> Double) {
}
performOperation method accepts an argument of type (Double, Double) -> Double.
Now this argument can be any of the below:
Method-1. A closure of type (Double, Double) -> Double
Method-2. A method name having signature as (Double, Double) -> Double
The below example uses both the methods:
func operation()
{
let operate = sender.currentTitle!
switch operate
{
case "+" : performOperation(operate: add) //using Method-2
case "-" : performOperation(){(a: Double, b: Double) -> Double in
return a - b
}//using Method-1
default: break
}
}
func add(a: Double, b: Double) -> Double
{
return a + b
}
func performOperation(operate: (Double, Double) -> Double)
{
let x = operate(3, 4)
print(x)
}
Similarly, you can use any of the 2 methods for all other cases of switch statement.

For debugging I would like println in functions with explicit return types

I keep getting error: type mismatch: found Uint required Double
When I put a println function in the sqrt method. While I appreciate its part of Scala preventing side effects, how do print values in functions so I can make sense of my programs? Is there a "clean" way to print values in a function that needs an explicit return type (like the recursive function sqrt)?
Code here:
object Newton {
def threshold(guess: Double, x: Double) : Boolean =
if (Math.abs(guess * guess -x) < (0.01/100 * x)) true else false
def improve(guess: Double, x: Double) : Double =
(guess + x/guess) / 2.0
def sqrt(guess: Double, x: Double,
threshold: (Double, Double) => Boolean,
improve: (Double, Double) => Double ): Double =
println("current guess:", guess)
if(threshold(guess,x))
return guess
else
return sqrt(improve(guess, x), x, threshold, improve)
def main(args: Array[String]): Unit = {
println("Sqrt of Two:", sqrt(1,1.0e-20,threshold, improve))
}
}
You are missing curly braces.
def sqrt(guess: Double, x: Double,
threshold: (Double, Double) => Boolean,
improve: (Double, Double) => Double ): Double = { // Add curly braces
println("current guess:", guess)
if(threshold(guess,x))
return guess
else
return sqrt(improve(guess, x), x, threshold, improve)
} // Add curly braces