It seems that Swift 4 does not support pattern matching tuple of enums - switch-statement

Is this a limitation in Swift 4 pattern matching or am I doing something wrong. I can't understand what the error message is referring to...
enum Event {
case scan
case stopScanning
}
enum State {
case idle
case scanning
}
let tuple: (State, Event) = (State.idle, Event.scan)
switch(tuple) {
case (.idle, .scan): return State.scanning
case (.scan, .stopScanning): return State.idle
default: return state
}
Produces error:
error: pattern cannot match values of type 'State'
case (.scan, .stopScanning): State.idle
~^~~~

(Immediately after writing the question I saw it... thanks SO for being my rubber duck. 🦆 I'm answering my own question in the hopes of saving somebody a little time if they get this error and don't immediately understand what it is saying and land here from google some day.)
The second case needs to have .scanning (State) not .scan (Event)
Following works:
let t: (State, Event) = (state, event)
switch(t) {
case (.idle, .scan): return State.scanning
case (.scanning, .stopScanning): return State.idle
default: return state
}
In retrospect, the Swift compiler was clearly telling me that the second case had incompatible enum value at 1st position in the tuple.

Related

Reduce nested match statements with unwrap_or_else in Rust

I have a rust program that has multiple nested match statements as shown below.
match client.get(url).send() {
Ok(mut res) => {
match res.read_to_string(&mut s) {
Ok(m) => {
match get_auth(m) {
Ok(k) => k,
Err(_) => return Err(“a”);
}
},
Err(_) => {
return Err(“b”);
}
}
},
Err(_) => {
return Err(“c”);
},
};
All the variables k and m are of type String.I am looking for a way to make the code more readable by removing excessive nested match statements keeping the error handling intact since both the output and the error types are important for the problem.Is it possible to achieve this by unwrap_or_else?
The .map_err() utility converts a Result to have a new error type, leaving the success type alone. It accepts a closure that consumes the existing error value and returns the new one.
The ? operator will early-return the error in the Err case, and unwrap in the Ok case.
Combining these two allows you to express this same flow succinctly:
get_auth(
client.get(url).send().map_err(|_| "c")?
.read_to_string(&mut s).map_err(|_| "b")?
).map_err(|_| "a")?
(I suspect that you actually want to pass s to get_auth() but that's not what the code in your question does, so I'm choosing to represent the code you posted instead of imaginary code that I'm guessing about.)

Swift WkWebView createWebArchiveData confused on return type

I am trying to capture the content displayed in a webview (not the source, which is a bunch of javascripts). I'm hoping wkwebview's createWebArchiveData is the right method.
So, where I am getting confused is what gets returned from the call.
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.createWebArchiveData(completionHandler: { (result) in
})
the docs say result is Result<data, error>. I did a type(of:) on it and the log printed Result<data, error>...thanks Apple...
when I printed result I got:
success(5990802 bytes)
thought maybe it was a tuple, but result.0 threw an error...
Value of type 'Result<Data, Error>' has no member '0'
tried to convert data to string...that didn't work...
tried to unarchive it, that failed as well.
Cannot convert value of type 'Result<Data, Error>' to expected argument type 'Data
so, any help would be appreciated. I need what is displayed on the screen, not the source code (in case I am going about this wrong).
I solved this. The Result object is an enum with two cases success and failure. You would read the value (in this case because it is Data) like so:
webView.createWebArchiveData(completionHandler: { (result) in
//var strResult = String(utf8String: result)
switch result {
case .success(let data):
let str = String(decoding: data, as: UTF8.self)
print(str)
case .failure(let error):
print(error)
}
})
You have get() method that will return data if result is success, less code for sure :)
if let data = try? result.get() {
//do something with data
}

Why is a match pattern with a guard clause not exhaustive?

Consider the following code sample (playground).
#[derive(PartialEq, Clone, Debug)]
enum State {
Initial,
One,
Two,
}
enum Event {
ButtonOne,
ButtonTwo,
}
struct StateMachine {
state: State,
}
impl StateMachine {
fn new() -> StateMachine {
StateMachine {
state: State::Initial,
}
}
fn advance_for_event(&mut self, event: Event) {
// grab a local copy of the current state
let start_state = self.state.clone();
// determine the next state required
let end_state = match (start_state, event) {
// starting with initial
(State::Initial, Event::ButtonOne) => State::One,
(State::Initial, Event::ButtonTwo) => State::Two,
// starting with one
(State::One, Event::ButtonOne) => State::Initial,
(State::One, Event::ButtonTwo) => State::Two,
// starting with two
(State::Two, Event::ButtonOne) => State::One,
(State::Two, Event::ButtonTwo) => State::Initial,
};
self.transition(end_state);
}
fn transition(&mut self, end_state: State) {
// update the state machine
let start_state = self.state.clone();
self.state = end_state.clone();
// handle actions on entry (or exit) of states
match (start_state, end_state) {
// transitions out of initial state
(State::Initial, State::One) => {}
(State::Initial, State::Two) => {}
// transitions out of one state
(State::One, State::Initial) => {}
(State::One, State::Two) => {}
// transitions out of two state
(State::Two, State::Initial) => {}
(State::Two, State::One) => {}
// identity states (no transition)
(ref x, ref y) if x == y => {}
// ^^^ above branch doesn't match, so this is required
// _ => {},
}
}
}
fn main() {
let mut sm = StateMachine::new();
sm.advance_for_event(Event::ButtonOne);
assert_eq!(sm.state, State::One);
sm.advance_for_event(Event::ButtonOne);
assert_eq!(sm.state, State::Initial);
sm.advance_for_event(Event::ButtonTwo);
assert_eq!(sm.state, State::Two);
sm.advance_for_event(Event::ButtonTwo);
assert_eq!(sm.state, State::Initial);
}
In the StateMachine::transition method, the code as presented does not compile:
error[E0004]: non-exhaustive patterns: `(Initial, Initial)` not covered
--> src/main.rs:52:15
|
52 | match (start_state, end_state) {
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(Initial, Initial)` not covered
But that is exactly the pattern I'm trying to match! Along with the (One, One) edge and (Two, Two) edge. Importantly I specifically want this case because I want to leverage the compiler to ensure that every possible state transition is handled (esp. when new states are added later) and I know that identity transitions will always be a no-op.
I can resolve the compiler error by uncommenting the line below that one (_ => {}) but then I lose the advantage of having the compiler check for valid transitions because this will match on any states added in the future.
I could also resolve this by manually typing each identity transition such as:
(State::Initial, State::Initial) => {}
That is tedious, and at that point I'm just fighting the compiler. This could probably be turned into a macro, so I could possibly do something like:
identity_is_no_op!(State);
Or worst case:
identity_is_no_op!(State::Initial, State::One, State::Two);
The macro can automatically write this boilerplate any time a new state is added, but that feels like unnecessary work when the pattern I have written should be covering the exact case that I'm looking for.
Why doesn't this work as written?
What is the cleanest way to do what I am trying to do?
I have decided that a macro of the second form (i.e. identity_is_no_op!(State::Initial, State::One, State::Two);) is actually the preferred solution.
It's easy to imagine a future in which I do want some of the states to do something in the 'no transition' case. Using this macro would still have the desired effect of forcing the state machine to be revisited when new States are added and would just require adding the new state to the macro arglist if nothing needs to be done. A reasonable compromise IMO.
I think the question is still useful because the behavior was surprising to me as a relatively new Rustacean.
Why doesn't this work as written?
Because the Rust compiler cannot take guard expressions into account when determining if a match is exhaustive. As soon as you have a guard, it assumes that guard could fail.
Note that this has nothing to do with the distinction between refutable and irrefutable patterns. if guards are not part of the pattern, they're part of the match syntax.
What is the cleanest way to do what I am trying to do?
List every possible combination. A macro could slightly shorten writing the patterns, but you can't use macros to replace entire match arms.

Compare enum without considering its arguments

Let me make this clear, I have this enum:
enum Token {
Number(v:Float);
Identifier(v:String);
TString(v:String);
Var;
Assign;
Division;
// and so on
}
I want to check if the value of a variable is an Identifier, but this doesn't work:
if(tk == Token.Identifier) {
It only allows me to compare the values if I pass arguments:
if(tk == Token.Identifier('test')) {
But this will only match if the identifier is 'test', but I want to match any identifier.
Type.enumConstructor(tk) == "Identifier"
Read the Type doc for more methods on enum.
Update (2019-02-04):
At the time of writing this answer it was still Haxe 2.06. Much have changed since then.
At this moment, for Haxe 3 (or 4), I would recommend pattern matching, specifically using single pattern check instead:
if (tk.match(Identifier(_)) ...
which is a short hand for
if (switch tk { case Identifier(_): true; case _: false; }) ...
_ is the wildcard that matches anything.
alternatively:
static function isIdentifier(token : Token) return switch(token) { case Token.Identifier(_): true; default: false; }
Using "using" you should also be able to do:
if(tk.isIdentifier()) {
Or even:
tk.match(Token.Identifier(_));

How does one return from a groovy closure and stop its execution?

I would like to return from a closure, like one would if using a break statement in a loop.
For example:
largeListOfElements.each{ element->
if(element == specificElement){
// do some work
return // but this will only leave this iteration and start the next
}
}
In the above if statement I would like to stop iterating through the list and leave the closure to avoid unnecessary iterations.
I've seen a solution where an exception is thrown within the closure and caught outside, but I'm not too fond of that solution.
Are there any solutions to this, other than changing the code to avoid this kind of algorithm?
I think you want to use find instead of each (at least for the specified example). Closures don't directly support break.
Under the covers, groovy doesn't actually use a closure either for find, it uses a for loop.
Alternatively, you could write your own enhanced version of find/each iterator that takes a conditional test closure, and another closure to call if a match is found, having it break if a match is met.
Here's an example:
Object.metaClass.eachBreak = { ifClosure, workClosure ->
for (Iterator iter = delegate.iterator(); iter.hasNext();) {
def value = iter.next()
if (ifClosure.call(value)) {
workClosure.call(value)
break
}
}
}
def a = ["foo", "bar", "baz", "qux"]
a.eachBreak( { it.startsWith("b") } ) {
println "working on $it"
}
// prints "working on bar"
I think you're working on the wrong level of abstraction. The .each block does exactly what it says: it executes the closure once for each element. What you probably want instead is to use List.indexOf to find the right specificElement, and then do the work you need to do on it.
If you want to process all elements until a specific one was found you could also do something like this:
largeListOfElements.find { element ->
// do some work
element == specificElement
}
Although you can use this with any kind of "break condition".
I just used this to process the first n elements of a collection by returning
counter++ >= n
at the end of the closure.
As I understand groovy, the way to shortcut these kinds of loops would be to throw a user-defined exception. I don't know what the syntax would be (not a grrovy programmer), but groovy runs on the JVM so it would be something something like:
class ThisOne extends Exception {Object foo; ThisOne(Object foo) {this.foo=foo;}}
try { x.each{ if(it.isOk()) throw new ThisOne(it); false} }
catch(ThisOne x) { print x.foo + " is ok"; }
After paulmurray's answer I wasn't sure myself what would happen with an Exception thrown from within a closure, so I whipped up a JUnit Test Case that is easy to think about:
class TestCaseForThrowingExceptionFromInsideClosure {
#Test
void testEearlyReturnViaException() {
try {
[ 'a', 'b', 'c', 'd' ].each {
System.out.println(it)
if (it == 'c') {
throw new Exception("Found c")
}
}
}
catch (Exception exe) {
System.out.println(exe.message)
}
}
}
The output of the above is:
a
b
c
Found c
But remember that "one should NOT use Exceptions for flow control", see in particular this Stack Overflow question: Why not use exceptions as regular flow of control?
So the above solution is less than ideal in any case. Just use:
class TestCaseForThrowingExceptionFromInsideClosure {
#Test
void testEarlyReturnViaFind() {
def curSolution
[ 'a', 'b', 'c', 'd' ].find {
System.out.println(it)
curSolution = it
return (it == 'c') // if true is returned, find() stops
}
System.out.println("Found ${curSolution}")
}
}
The output of the above is also:
a
b
c
Found c
Today I faced a similar problem while working with each closure. I wanted to break the flow of execution based on my condition but couldn't do it.
The easiest way to do in groovy is to use any() on a list instead of each if you wish to return a boolean based on some condition.
Good ole for loop still works in Groovy for your use case
for (element in largeListOfElements) {
if(element == specificElement){
// do some work
return
}
}

Resources