Match returning straight input in all but one case [duplicate] - return

This question already has answers here:
How to map a parametrized enum from a generic type to another?
(4 answers)
Closed 7 years ago.
Let's say I have an enum like this
pub enum Status<T> {
Error,
NotStarted,
Incomplete,
Complete(T),
}
and I want to do this
match foo(x) {
Complete(i) => Complete(bar(i)),
Error => Error,
NotStarted => NotStarted,
Incomplete => Incomplete,
}
i.e. only do something with it, if it matched one "special" option and return match input unseen otherwise. In my code this happens a lot.
Is there another way to do this in a shorter way? Probably something like this:
match foo(x) {
Complete(i) => Complete(bar(i)),
_ => _,
}

Just bind the other cases to a name and return that
match foo(x) {
Complete(i) => Complete(bar(i)),
other => other,
}

Related

Returning a constructed recursive data structure in Rust

I've just started learning Rust and am coming from a functional programming background. I'm trying to create a parser in rust and have defined this recursive data structure
enum SimpleExpression<'a> {
Number(u64),
FunctionCall(Function, &'a SimpleExpression<'a>, &'a SimpleExpression<'a>)
}
I initially had defined it as
enum SimpleExpression {
Number(u64),
FunctionCall(Function, SimpleExpression, SimpleExpression)
}
but got a complaint from the compiler saying this type had an infinite size. I'm not used to having to worry about managing memory so this confused me for a second but now it makes a lot of sense. Rust cannot allocate memory for a data structure where the size is not defined. So changing the SimpleExpression to &'a SimpleExpression<'a> makes sense.
The second problem I came across was when implementing the parsing function (excuse the verboseness)
fn parse_simple_expr(input: &str) -> Option<(SimpleExpression, usize)> {
match parse_simple_expr(&input) {
Some((left, consumed1)) => match parse_function_with_whitespace(&input[consumed1..]) {
Some((func, consumed2)) => match parse_simple_expr(&input[consumed1+consumed2..]) {
Some((right, consumed3)) => Some((
SimpleExpression::FunctionCall(func, &left.clone(), &right.clone()),
consumed1 + consumed2 + consumed3
)),
None => None
},
None => None
},
None => None
}
}
But basically what is wrong with this function is I am creating SimpleExpression objects inside the function and then trying to return references to them from the function. The problem here of course is that the objects will be dropped when the function returns and Rust does not allow dangling references so I get the error cannot return value referencing temporary value on &left.clone() and &right.clone().
It makes sense to me why this does not work but I am wondering if there is another way to execute this pattern to be able to create a recursive object and return it from a function. Or is there some fundamental reason this will never work in which case are there any good alternatives? Since my code is confusing I've also provided a simpler example of a recursive structure but that has the same limitations in case that helps to better understand the issue.
enum List<'a> {
End,
Next((char, &'a List<'a>))
}
fn create_linked(input: &str) -> List {
match input.chars().next() {
Some(c) => List::Next((c, &create_linked(&input[1..]))),
None => List::End
}
}

Dart type tests work differently between local variable and class member variables [duplicate]

This question already has an answer here:
Smart cast (automatic type promotion) using 'is' is not working
(1 answer)
Closed 2 years ago.
I am working with dart without allowing implicit dynamics and casts and I noticed the following:
When working with a local variable, I can use a type check on that variable and if the test passes, the compiler will just assume that I can use that variable as that type:
var emp; // set to something
if (emp is Person) {
// The compiler infers that emp is a person within this scope
// so it allows me to use Person's member functions and variables
// without the need for explicit typecast
// https://dart.dev/guides/language/language-tour#type-test-operators
emp.firstName = 'Bob';
}
However, this does not work if the variable is the member variable of an object:
class SuperPerson {
Object _emp;
/* Various things that could be doing things with _emp here */
void memberFun() {
if (_emp is Person) {
_emp.firstName = 'Bob'; // ERROR: The setter firstName is not defined for type Object.
(_emp as Person).firstName = 'Bob'; // workaround but would like to avoid casts that could fail.
}
}
}
Why is that and how can I overcome it?
Could it be because of potentially other threads changing the value of _emp in between the test and the use?
Edit: I had forgotten that I had already answered this question. See that one instead.
(Since this answer had already been accepted at the time of this edit, I cannot delete it.)

What is the -> (dash greater than) operator in Ruby/Rails [duplicate]

This question already has answers here:
What is the -> (stab) operator in Ruby? [duplicate]
(1 answer)
What does -> mean in Ruby [duplicate]
(2 answers)
Closed 9 years ago.
I just ran across the following line of code in a Rails app:
scope :for_uid, ->(external_id) { where(external_id: external_id) }
What does the -> operator mean? It's kind of hard to Google.
This is syntactic sugar.
->(external_id) { where(external_id: external_id) }
is equal to:
lambda { |external_id| where(external_id: external_id) }
It's new lambda notation. This syntax was introduced in ruby 1.9, and is used to define unnamed functions.
In your example it is scope defined by unnamed function.
The -> operator was introduced in Ruby 1.9 as a shorthand syntax for the old lambda function. It behaves nearly identically to the lambda function but allows you to specify parameters outside the block:
lambda {|param| puts param }
# becomes
-> (param) { puts params }

How should I respond with different status codes to a GET request in Spray?

For POST and PUT requests I use the following syntax:
put {
entity(as[CaseClass]) { entity =>
returnsOption(entity).map(result => complete{(Created, result)})
.getOrElse(complete{(NotFound, "I couldn't find the parent resource you're modifying")})
}
}
Now for GET requests I'm trying to do the same, but I can't get it to work analogously to my PUT solution. What is a good way to do this with GET requests?
Update:
I've got this working with the following hack:
(get & parameters('ignored.?)) {
//TODO find a way to do this without ignored parameters
(ingored:Option[String]) => {
returnsOption().map(result => complete(result))
.getOrElse(complete{(NotFound, "")})
}
}
I'd expect something similar to be possible with () => or ctx => , but that doesn't fly, because it gives trouble with marshalling:
... could not find implicit value for evidence parameter of type spray.httpx.marshalling.Marshaller[(spray.http.StatusCodes.ClientError, String)]
}).getOrElse(ctx.complete{(NotFound, "")})
^
Could it be that this somehow relates to the fact that I'm using spray-json?
Use HttpResponse like this for example
complete{
HttpResponse(StatusCodes.OK, HttpBody(ContentType(`text/html`), "test test: " + System.currentTimeMillis.toString))
}
Update: I've been using Spray for a while now. Turned out there is better way:
complete {
StatusCodes.BandwidthLimitExceeded -> MyCustomObject("blah blah")
}
This code should work:
get {
ctx =>
ctx.complete(returnsOption())
}
If don't use ctx => at the start, your code might only be executed at route build time.
Here you can find some explanations: Understanding the DSL Structure

How to write a Parser that validates its input against a predicate and otherwise fails

I want to write a Parser that produces some data structure and validates its consistency by running a predicate on it. In case the predicate returns false the parser should return a custom Error object (as opposed to a Failure, since this can be achieved by ^?).
I am looking for some operator on parser that can achieve that.
For example, let's say that I want to parse a list of integers and check that they are distinct. I would like to have something like this:
import util.parsing.combinator.RegexParsers
object MyParser extends RegexParsers {
val number: Parser[Int] = """\d+""".r ^^ {_.toInt }
val list = repsep(number, ",") ^!(checkDistinct, "numbers have to be unique")
def checkDistinct(numbers: List[Int]) = (numbers.length == numbers.distinct.length)
}
The ^! in the code above is what I am looking for. How can I validate a parser output and return a useful error message if it does not validate?
One way to achieve this would be to use the Pimp My Library pattern to add the ^! operator to Parser[List[T]] (the return type of repsep). Define an implicit def, then import it into scope when you need to use it:
class ParserWithMyExtras[T](val parser:Parser[List[T]]){
def ^!(predicate:List[T]=>Boolean, errorMessage:String) = {...}
}
implicit def augmentParser[T](parser:Parser[List[T]]) =
new ParserWithMyExtras(parser)
Parsers.commit transforms Failure to Error.
So a first step would be
commit(p ^?(condition, message))
However this would give an error if p gives a failure, which I suppose is not what you want, you want an error only when p succeeds and then the check fails.
So you should rather do
p into {result => commit(success(result) ^? (condition,message))}
That may sound rather contrived, you may also implement directly, just copy the implementation of ^? replacing failure with an error.
Finally you should probably do as suggested by Dylan and add the operator. If you want to do it outside of your grammar (Parsers) , I think you will need a mixin:
trait PimpedParsers { self: Parsers =>
implicit def ...
}
Otherwise you cannot easily refer to (single) Parser.
Here is a complete Pimp My Library implementation:
implicit def validatingParsers[T](parser: Parser[T]) = new {
def ^!(predicate: T => Boolean, error: => String) = Parser { in =>
parser(in) match {
case s #Success(result, sin) => predicate(result) match {
case true => s
case false => Error(error, sin) // <--
}
case e #NoSuccess(_, _) => e
}
}
}
The new operator ^! transforms the parser on the left to a new parser that applies the predicate.
One important thing to note is the sin on the line marked with <--. Because the Error that is eventually returned by Scala's parser library is the one in the latest position in the input, it is crucial to pass sin in that line instead of in, as sin represents the point where the inner parser completed its own parsing.
If we passed in instead of sin, the error that would eventually be reported could be the latest failure that happened during the parsing of the inner rule (which we know that eventually succeeded if we got to that line).
^? accepts an error message generator, commit converts a Failure to an Error:
val list = commit {
repsep(number, ",") ^? (
{ case numbers if checkDistinct(numbers) => true},
_ => "numbers have to be unique" )
}

Resources