I was playing around with some possible ways to extract several values at once from a Swift dictionary. The goal is to do something like this:
var dict = [1: "one", 2: "two", 3: "three"]
dict.multiSubscript(2...4) // Should yield ["two", "three", nil]
or this:
dict.multiSubscript([1, 2]) // Should yield ["one", "two"]
In other words, it seems like it should be possible to implement multiSubscript() generically for any SequenceType-conformant subscript type.
However, Swift doesn’t seem to like the following implementation, and the error message isn’t very illuminating:
extension Dictionary {
func multiSubscript<S: SequenceType where S.Generator.Element == Key>(seq: S) -> [Value?] {
var result = [Value?]()
for seqElt in seq { // ERROR: Cannot convert the expression's type 'S' to type 'S'
result += self[seqElt]
}
return result
}
}
This seems like a relatively straightforward use of constraints on generics. Does anyone see what I’m doing wrong?
For bonus points, is there a way to implement this to allow the use of normal subscripting syntax? For example:
dict[2...4] // Should yield ["two", "three", nil]
I'm not entirely sure why for seqElt in seq doesn't work (I suspect a bug), but using SequenceOf<Key>(seq) in the for-in works:
func multiSubscript<S: SequenceType where S.Generator.Element == Key>(seq: S) -> [Value?] {
var result = [Value?]()
for seqElt in SequenceOf<Key>(seq) {
result.append(self[seqElt])
}
return result
}
Also note that result += self[seqElt] didn't work; I used result.append(self[seqElt]) instead.
Related
I'm learning Rust and would like to know how I can improve the code below.
I have a vector of tuples of form (u32, String). The u32 values represent line numbers and the Strings are the text on the corresponding lines. As long as all the String values can be successfully parsed as integers, I want to return an Ok<Vec<i32>> containing the just parsed String values, but if not I want to return an error of some form (just an Err<String> in the example below).
I'm trying to learn to avoid mutability and use functional styles where appropriate, and the above is straightforward to do functionally if that was all that was needed. Here's what I came up with in this case:
fn data_vals(sv: &Vec<(u32, String)>) -> Result<Vec<i32>, String> {
sv.iter()
.map(|s| s.1.parse::<i32>()
.map_err(|_e| "*** Invalid data.".to_string()))
.collect()
}
However, the small catch is that I want to print an error message for every invalid value (and not just the first one), and the error messages should contain both the line number and the string values in the offending tuple.
I've managed to do it with the following code:
fn data_vals(sv: &Vec<(u32, String)>) -> Result<Vec<i32>, String> {
sv.iter()
.map(|s| (s.0, s.1.parse::<i32>()
.or_else(|e| {
eprintln!("ERROR: Invalid data value at line {}: '{}'",
s.0, s.1);
Err(e)
})))
.collect::<Vec<(u32, Result<i32, _>)>>() // Collect here to avoid short-circuit
.iter()
.map(|i| i.1
.clone()
.map_err(|_e| "*** Invalid data.".to_string()))
.collect()
}
This works, but seems rather messy and cumbersome - especially the typed collect() in the middle to avoid short-circuiting so all the errors are printed. The clone() call is also annoying, and I'm not really sure why it's needed - the compiler says I'm moving out of borrowed content otherwise, but I'm not really sure what's being moved. Is there a way it can be done more cleanly? Or should I go back to a more procedural style? When I tried, I ended up with mutable variables and a flag to indicate success and failure, which seems less elegant:
fn data_vals(sv: &Vec<(u32, String)>) -> Result<Vec<i32>, String> {
let mut datavals = Vec::new();
let mut success = true;
for s in sv {
match s.1.parse::<i32>() {
Ok(v) => datavals.push(v),
Err(_e) => {
eprintln!("ERROR: Invalid data value at line {}: '{}'",
s.0, s.1);
success = false;
},
}
}
if success {
return Ok(datavals);
} else {
return Err("*** Invalid data.".to_string());
}
}
Can someone advise me on the best way to do this? Should I stick to the procedural style here, and if so can that be improved? Or is there a cleaner functional way to do it? Or a blend of the two? Any advice appreciated.
I think that's what partition_map() from itertools is for:
use itertools::{Either, Itertools};
fn data_vals<'a>(sv: &[&'a str]) -> Result<Vec<i32>, Vec<(&'a str, std::num::ParseIntError)>> {
let (successes, failures): (Vec<_>, Vec<_>) =
sv.iter().partition_map(|s| match s.parse::<i32>() {
Ok(v) => Either::Left(v),
Err(e) => Either::Right((*s, e)),
});
if failures.len() != 0 {
Err(failures)
} else {
Ok(successes)
}
}
fn main() {
let numbers = vec!["42", "aaaezrgggtht", "..4rez41eza", "55"];
println!("{:#?}", data_vals(&numbers));
}
In a purely functional style, you have to avoid side-effects.
Printing errors is a side-effect. The preferred style would be to return an object of the style:
Result<Vec<i32>, Vec<String>>
and print the list after the data_vals function returns.
So, essentially, you want your processing to collect a list of integers, and a list of strings:
fn data_vals(sv: &Vec<(u32, String)>) -> Result<Vec<i32>, Vec<String>> {
let (ok, err): (Vec<_>, Vec<_>) = sv
.iter()
.map(|(i, s)| {
s.parse()
.map_err(|_e| format!("ERROR: Invalid data value at line {}: '{}'", i, s))
})
.partition(|e| e.is_ok());
if err.len() > 0 {
Err(err.iter().filter_map(|e| e.clone().err()).collect())
} else {
Ok(ok.iter().filter_map(|e| e.clone().ok()).collect())
}
}
fn main() {
let input = vec![(1, "0".to_string())];
let r = data_vals(&input);
assert_eq!(r, Ok(vec![0]));
let input = vec![(1, "zzz".to_string())];
let r = data_vals(&input);
assert_eq!(r, Err(vec!["ERROR: Invalid data value at line 1: 'zzz'".to_string()]));
}
Playground Link
This uses partition which does not depend on an external crate.
Side effects (eprintln!) in an iterator adapter are definitely not "functional". You should accumulate and return the errors and let the caller deal with them.
I would use fold here. The goal of fold is to reduce a list to a single value, starting from an initial value and augmenting the result with every item. This "single value" can very well be a list, though. Here, though, there are two possible lists we might want to return: a list of i32 if all values are valid, or a list of errors if there are any errors (I've chosen to return Strings for errors here, for simplicity.)
fn data_vals(sv: &[(u32, String)]) -> Result<Vec<i32>, Vec<String>> {
sv.iter().fold(
Ok(Vec::with_capacity(sv.len())),
|acc, (line_number, data)| {
let data = data
.parse::<i32>()
.map_err(|_| format!("Invalid data value at line {}: '{}'", line_number, data));
match (acc, data) {
(Ok(mut acc_data), Ok(this_data)) => {
// No errors yet; push the parsed value to the values vector.
acc_data.push(this_data);
Ok(acc_data)
}
(Ok(..), Err(this_error)) => {
// First error: replace the accumulator with an `Err` containing the first error.
Err(vec![this_error])
}
(Err(acc_errors), Ok(..)) => {
// There have been errors, but this item is valid; ignore it.
Err(acc_errors)
}
(Err(mut acc_errors), Err(this_error)) => {
// One more error: push it to the error vector.
acc_errors.push(this_error);
Err(acc_errors)
}
}
},
)
}
fn main() {
println!("{:?}", data_vals(&[]));
println!("{:?}", data_vals(&[(1, "123".into())]));
println!("{:?}", data_vals(&[(1, "123a".into())]));
println!("{:?}", data_vals(&[(1, "123".into()), (2, "123a".into())]));
println!("{:?}", data_vals(&[(1, "123a".into()), (2, "123".into())]));
println!("{:?}", data_vals(&[(1, "123a".into()), (2, "123b".into())]));
}
The initial value is Ok(Vec::with_capacity(sv.len())) (this is an optimization to avoid reallocating the vector as we push items to it; a simpler version would be Ok(vec![])). If the slice is empty, this will be fold's result; the closure will never be called.
For each item, the closure checks 1) whether there were any errors so far (indicated by the accumulator value being an Err) or not and 2) whether the current item is valid or not. I'm matching on two Result values simultaneously (by combining them in a tuple) to handle all 4 cases. The closure then returns an Ok if there are no errors so far (with all the parsed values so far) or an Err if there are any errors so far (with every invalid value found so far).
You'll notice I used the push method to add an item to a Vec. This is, strictly speaking, mutation, which is not considered "functional", but because we are moving the Vecs here, we know there are no other references to them, so we know we aren't affecting any other use of these Vecs.
I'm trying to force myself to employ functional programming in Kotlin, and wherever possible, avoid using mutable vars. Ordinarily, for an ad hoc test for a unit-returning function, I'd just println() something inside the function to see if it's working right. But for this test, I need to accumulate a string and then ultimately use assertEquals(...).
As usual, I found myself declaring a var in the enclosing scope and using += to accumulate into it. Is there a more functional way to do this by passing/chaining a function and eliminating the mutable var? Here's some simplified but illustrative code:
inline fun <T> Iterable<T>.forEachFrom(beg:Int, act:(T)->Unit) {
var i=0; if (beg>=0) for (e in this) if (i++ >= beg) act(e)
}
fun main(args:Array<String>) {
val l = listOf("zero", "one", "two", "three", "four")
// print-to-screen test
l.forEachFrom(2){print("$it-")}; println()
// output: two-three-four-
// accumulate-in-var test
var s = ""
l.forEachFrom(2){s += "$it-"}; println(s)
// output: two-three-four-
// Is there a purely functional way, without declaring a mutable var?
// val s = l.forEachFrom(2){accumulator???("$it-")}
// - OR -
// val s = l.forEachFrom(2).accumulator???("$it-")
// println(s)
}
A way to do the same with only kotlin-stdlib and retain the semantics of the code (i.e. iterate only once) is to convert the Iterable<T> to Sequence<T> and use the .drop(n) extension:
inline fun <T> Iterable<T>.forEachFrom(beg: Int, act: (T) -> Unit) =
if (beg >= 0)
asSequence().drop(beg).forEach(act) else
Unit
UPD: After discussing the overall question, we came up with another approach.
When you have a custom higher-order function that iterates over the items and only accepts a callback but does not return anything, you can wrap that custom iteration logic into a Sequence<T> by using buildSequence { ... } and passing yield(it) as the callback:
val sequenceFromCustomFunction = buildSequence {
l.forEachFrom(2) { yield(it) }
}
This allows you to work with this sequence in functional style and, in particular, fold the sequence:
val s = sequenceFromCustomFunction.fold("") { acc, it -> acc + it + "-" }
I'm trying to access an element a dictionary element and downcast it to a type other than AnyObject but keep getting the same compiler error: Could not find an overload for 'subscript' that accepts the supplied arguments.
I know I can just do this using two if statements like so:
if let x = dict["key"] {
if let y = x as? String {
// ...
}
}
But I feel there has to be a more elegant solution than this. The format that makes the most sense to me is:
if let x = dict["key"] as? String {
// ...
}
But this just results in the error, mentioned above. I've tried dozens of variations of this, but none of it seems to make any difference. Is this something that just can't be done in Swift?
The reason your desired formulation isn't working is that you're trying to unwrap two Optionals with a single as?. There are two Optionals because both the subscripting of your dictionary and the attempted cast to String return optional values. There isn't a way to do it in one if statement that will be runtime-safe, but there is a way:
if let x = dict["key"]! as? String {
println(x)
}
The problem is that if dict["key"] ends up being nil, the forced unwrapping will crash your app. Better to do it this way (you can skip the first if), even if it is an extra step:
let x: AnyObject? = dict["key"]
if let y = x as? String {
println(y)
}
The extra step is just the cost of working with a Dictionary<String, AnyObject> - if you can get your dictionary type more specific, you won't have to do it any more.
I was also struggling with this thing but then i fount out that optional chaining is the solution. Just use
if let x = dict["key"]? as? String {
println(x)
}
It gives you both the safety and compactness.
In the end I had to use this one-line solution:
if let name = jsonDict["name"] as AnyObject? as? String {
println("name is \(name)")
} else {
println("property was nil")
}
I have a variable of type value that stores a map, but I can not access the values by providing the keys:
rascal>a
value: ("s":"s")
rascal>a["s"]
|stdin:///|(2,3,<1,2>,<1,5>): subscript not supported on value at |stdin:///|(2,3,<1,2>,<1,5>)
☞ Advice
How can I parse the value to map in order to be able to retrieve my value ?
if (map[str,str] myMap := a) {
// do stuff with myMap
}
else {
throw "<a> is not a map?";
}
Another way of "narrowing types" is using pattern matching in function parameters:
rascal>value x = 1;
int: 1
rascal>int myFunc(int i) = 2 * i;
ok
rascal>myFunc(x);
int: 2
And yet another way is using visit or switch:
visit(bigValue) {
case Expression e => ...work with e...
}
The general idea is:
pattern matching means narrowing (downcasting)
pattern matching may fail and so is always in a conditional context
there are many places in Rascal where you can use pattern matching: function dispatch, switch, visit, :=, <-
Can I retrieve a Method via reflection, somehow combine it with a target object, and return it as something that looks like a function in Scala (i.e. you can call it using parenthesis)? The argument list is variable. It doesn't have to be a "first-class" function (I've updated the question), just a syntactic-looking function call, e.g. f(args).
My attempt so far looks something like this (which technically is pseudo-code, just to avoid cluttering up the post with additional definitions):
class method_ref(o: AnyRef, m: java.lang.reflect.Method) {
def apply(args: Any*): some_return_type = {
var oa: Array[Object] = args.toArray.map { _.asInstanceOf[Object] }
println("calling: " + m.toString + " with: " + oa.length)
m.invoke(o, oa: _*) match {
case x: some_return_type => x;
case u => throw new Exception("unknown result" + u);
}
}
}
With the above I was able to get past the compiler errors, but now I have a run-time exception:
Caused by: java.lang.IllegalArgumentException: argument type mismatch
The example usage is something like:
var f = ... some expression returning method_ref ...;
...
var y = f(x) // looks like a function, doesn't it?
UPDATE
Changing the args:Any* to args:AnyRef* actually fixed my run-time problem, so the above approach (with the fix) works fine for what I was trying to accomplish. I think I ran into a more general issue with varargs here.
Sure. Here's some code I wrote that add an interface to a function. It's not exactly what you want, but I think it can be adapted with few changes. The most difficult change is on invoke, where you'll need to change the invoked method by the one obtained through reflection. Also, you'll have to take care that the received method you are processing is apply. Also, instead of f, you'd use the target object. It should probably look something like this:
def invoke(proxy: AnyRef, method: Method, args: Array[AnyRef]) = method match {
case m if /* m is apply */ => target.getClass().getMethod("name", /* parameter type */).invoke(target, args: _*)
case _ => /* ??? */
}
Anyway, here's the code:
import java.lang.reflect.{Proxy, InvocationHandler, Method}
class Handler[T, R](f: Function1[T, R])(implicit fm: Manifest[Function1[T, R]]) extends InvocationHandler {
def invoke(proxy: AnyRef, method: Method, args: Array[AnyRef]) = method.invoke(f, args: _*)
def withInterface[I](implicit m: Manifest[I]) = {
require(m <:< manifest[Function1[T, R]] && m.erasure.isInterface)
Proxy.newProxyInstance(m.erasure.getClassLoader(), Array(m.erasure), this).asInstanceOf[I]
}
}
object Handler {
def apply[T, R](f: Function1[T, R])(implicit fm: Manifest[Function1[T, R]]) = new Handler(f)
}
And use it like this:
trait CostFunction extends Function1[String, Int]
Handler { x: String => x.length } withInterface manifest[CostFunction]
The use of "manifest" there helps with syntax. You could write it like this:
Handler({ x: String => x.length }).withInterface[CostFunction] // or
Handler((_: String).length).withInterface[CostFunction]
One could also drop the manifest and use classOf instead with a few changes.
If you're not looking for a generic invoke that takes the method name--but rather, you want to capture a particular method on a particular object--and you don't want to get too deeply into manifests and such, I think the following is a decent solution:
class MethodFunc[T <: AnyRef](o: Object, m: reflect.Method, tc: Class[T]) {
def apply(oa: Any*): T = {
val result = m.invoke(o, oa.map(_.asInstanceOf[AnyRef]): _*)
if (result.getClass == tc) result.asInstanceOf[T]
else throw new IllegalArgumentException("Unexpected result " + result)
}
}
Let's see it in action:
val s = "Hi there, friend"
val m = s.getClass.getMethods.find(m => {
m.getName == "substring" && m.getParameterTypes.length == 2
}).get
val mf = new MethodFunc(s,m,classOf[String])
scala> mf(3,8)
res10: String = there
The tricky part is getting the correct type for the return value. Here it's left up to you to supply it. For example,if you supply classOf[CharSequence] it will fail because it's not the right class. (Manifests are better for this, but you did ask for simple...though I think "simple to use" is generally better than "simple to code the functionality".)