Pattern Match and Conditionally Bind in a Single Switch Statement

Pattern match and conditionally bind in a single Switch statement

Sure, you can use the conditional casting pattern case let x as Type:

let x: Any = "123"

switch x {
case let s as String:
print(s) //use s
case let i as Int:
print(i) //use i
case let b as Bool:
print(b) //use b
default:
fatalError()
}

Evaluate a conditional as well as bind its result in pattern match?

No, this is one of the weaknesses of Scala's pattern matching syntax. What you can do is use a custom extractor:

class FunctionExtractor[A, B](f: A => B) {
def unapply(a: A): Option[B] = Some(f(a))
}
val LengthyEvaluation1 = new FunctionExtractor(lengthyEvaluation1)
val LengthyEvaluation2 = new FunctionExtractor(lengthyEvaluation2)

c match {
case LengthyEvaluation1(res) if res > 0 => res.toString
case LengthyEvaluation2(res) if res > 0 => res.toString
}

Pattern matching in a Swift for loop

You can combine a pattern matching conditional cast with a where clause like so:

let myStuff: [AnyObject] = [5, "dog", 11, 15, "cat"]

// item will be an Int, and divisible by 5
for case let item as Int in myStuff where item % 5 == 0 {
print(item)
}

// Prints:
// 5
// 15

How to get index in for case pattern matching loop

You can use enumerated() in conjunction with for case let, you just need to move the conditional typecasting pattern into the binding of the second element in the tuple.

// note that variable names should be lowerCamelCase – I renamed 'JSON' to 'json'.
for case let (index, playlistData as JSONDictionary) in json.enumerated() {
// ...
}

enumerated() returns a sequence of pairs of consecutive Ints starting from 0 (available inside the loop as index) along with the elements of the sequence you call it on.

Bound expressions inside a condition in a cond block in Elixir?

To directly answer the first question, the answer is yes. Your original code:

cond do
a = 1; a * 2 == 2 -> "Yes"
end

Is parsed as:

cond do
a = 1
a * 2 == 2 -> "Yes"
end

Because ; means the end of the whole expression. In case you want to include multiple expressions, use parens:

cond do
(a = 1; a * 2 == 2) -> "Yes"
end

Is it possible to write compound switch case between enum associated value conditional and another enum case?

You don't need a where-clause to match .cloudy(coverage: 0), just

case .cloudy(coverage: 0), .sunny: 
print("☀️")

Another option is to use fallthrough, for example

case .cloudy(let coverage) where coverage < 10:
fallthrough
case .sunny:
print("☀️")

Compound switch cases: may we have a single common value binding for compound enum cases that have the same type of associated value?

No, this is not possible; in the value binding examples above, x must be bound in every pattern, and this must hold separately for every pattern in the compound cases.

Quoting the Language Guide - Control Flow [emphasis mine]

Compound cases can also include value bindings. All of the patterns of
a compound case have to include the same set of value bindings, and
each binding has to get a value of the same type from all of the
patterns in the compound case
. This ensures that, no matter which part
of the compound case matched, the code in the body of the case can
always access a value for the bindings
and that the value always has
the same type.

I we try to omit the binding in one of the patterns in the compound example above, we are given quite an self-explanatory error message on the subject:

func foo(_ foo: Foo) -> Int {
switch foo {
case .bar(_), .baz(let x), .bax(let x): return x
case .fox: return 0
}
}
error: 'x' must be bound in every pattern

This holds even if we don't use x in the body that follows

func foo(_ foo: Foo) -> Int {
switch foo {
case .bar(_), .baz(let x), .bax(let x): return 0
case .fox: return 0
}
} // same error


Related Topics



Leave a reply



Submit