Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional chaining in swift with arbitrary operations?

Apple supplies an example of succinct optional chaining

class Person {
  var residence: Residence?
}

class Residence {
  var numberOfRooms = 1
}

let john = Person()

if let roomCount = john.residence?.numberOfRooms {
  println("John's residence has \(roomCount) room(s).")
} else {
  println("Unable to retrieve the number of rooms.")
}

Imagine trying to adjust the condition with some arithmetic operations. This results in a compiler error as the modulo operator doesn't support optionals.

if john.residence?.numberOfRooms % 2 == 0 { 
  // compiler error: Value of optional type Int? not unwrapped
  println("John has an even number of rooms")
} else {
  println("John has an odd number of rooms")
}

Of course you could always do something like the following, but it lacks the simplicity and succinctness of optional chaining.

if let residence = john.residence {
  if residence.numberOfRooms % 2 == 0  {
    println("John has an even number of rooms")
  }else{
    println("John has an odd number of rooms")
  }
} else {
  println("John has an odd number of rooms")
}

Are there any Swift language features which might provide a better solution?

like image 910
Grantismo Avatar asked Jun 17 '14 19:06

Grantismo


People also ask

What problem does Optional chaining solve in Swift?

You can use optional chaining with calls to properties, methods, and subscripts that are more than one level deep. This enables you to drill down into subproperties within complex models of interrelated types, and to check whether it's possible to access properties, methods, and subscripts on those subproperties.

What is the difference between optional chaining and optional binding in Swift?

Difference between Optional Chaining and Optional Binding: 1. Optional binding stores the value that you're binding in a variable. 2. Optional chaining doesn't allows an entire block of logic to happen the same way every time.

What is the use of optional chaining?

The optional chaining operator ( ?. ) enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.

What is optional binding in Swift?

Optional binding is a mechanism built into Swift to safely unwrap optionals. Since an optional may or may not contain a value, optional binding always has to be conditional. To enable this, conditional statements in Swift support optional binding, which checks if a wrapped value actually exists.


2 Answers

I think what you are looking for is generally called a monad in functional programming.

It is not directly available in swift, but by using some of the language features, you can implement monads yourself in a generic way. (And also define a nice looking infix operator that makes it look like the monads in Haskell)

A quick google search for "monad swift" turned up some promising looking code at https://gist.github.com/cobbal/7562875ab5bfc6f0aed6

like image 178
powerpete Avatar answered Oct 11 '22 10:10

powerpete


Pattern matching is quite powerful, and can work in situations like this:

switch john.residence?.numberOfRooms {
case .Some(let x) where x % 2 == 0:
    println("Even number of rooms")
default:
    println("Odd number of rooms")
}
like image 20
Wes Campaigne Avatar answered Oct 11 '22 11:10

Wes Campaigne