Is it possible to use Sweet.Js to expand
{ "foo": "bar" }
to
{ "bar": "foo" }
for example?
My naïve attempt here doesn’t work and I don’t see an example in the documentation.
Thanks.
The trick is that : has special meaning in patterns so you need to escape it with $[:]
macro bar {
rule { {$x $[:] $y} } => { {$y: $x} }
}
var o = bar { "bax": "quux" }
Related
I'm trying create a "conversion" Protocol, to which a Dictionary can conform to if its values implement said protocol.
import Foundation
protocol Fooable {
var foo:String { get }
}
extension Double:Fooable {
var foo:String { get { return "number" } }
}
extension Int:Fooable {
var foo:String { get { return "count" } }
}
extension String:Fooable {
var foo:String { get { return "name" } }
}
extension Dictionary:Fooable where Key == String, Value:Fooable {
var foo:String {
get {
var result = "["
self.keys.sorted().forEach { key in
result += key
result += ": "
result += self[key]!.foo
}
result += "]"
return result
}
}
}
["a": 6.28, "b": 42, "c": "boo"].foo
The problem is that the last line is deemed ambiguous:
error: type of expression is ambiguous without more context
["a": 6.28, "b": 42, "c": "boo"].foo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
Is what I'm trying to do even doable? What do I have to change or add to make it work?
UPDATE
Type Erasure seems to be one "solution". So basically, I would need to make something like:
struct AnyFoo<Fooable> { }
At this point, I can now wrap/erase everything in my dictionary literal:
["a": AnyFoo(6.28), "b": AnyFoo(42), "c": AnyFoo("boo")].foo
along with refining the extension of Dictionary to be for Dictionary's where Value is AnyFoo. Is this really any better than just constricting the Dictionary's extension to cases where Value is String instead and just doing:
["a": 6.28.foo, "b": 42.foo, "c": "boo".foo].foo
For a simple "convert" case, I'm not sure what I would gain from using TypeErasure to defer the conversion through a wrapper, vs just converting before dictionary creation. Less actual typing (as in character input) to do the latter. So I haven't really gained any thing.
Unless I'm missing something, for my case, I'll probably just go with downcasts (e.g. as? Fooable) for container elements, and do something like log errors or something.
Given this simple macro that expands multiple items, how could this take a macro as an argument?
macro_rules! print_structs {
($($t:ty)*) => ($(
println!("{:?}", TypeId::of::<$t>());
)*)
}
// expands one println per type!
print_structs! { i8 i16 usize String }
How could a pre-defined macro of types be passed in?
Example of non-working macro:
macro_rules! some_types {
() => {
i8 i16 usize String
}
}
print_structs! { some_types!() }
See play.rust-lang.org example, uncomment UNCOMMENT TO TEST lines to see the problem.
Gives the error: macro expansion ignores token `i16` and any following
I also tried to put the list in a file to include, eg:
print_structs! {
include!("some_types.in")
}
... however this gives an error: expected type, found `include!("../struct_list.rs")`
From looking into this, it seems that its not possible to expand a list inside a macro using a macro or include.
Although code-generation is an option, its quite involved so will leave it out of this answer.
It is possible to get similar functionality by swapping macro use around, instead of passing the list into a macro, pass a macro name into a generic macro that expand it with a list.
Heres a working example:
macro_rules! print_structs {
($($t:ty)*) => ($(
println!("{:?}", ::std::any::TypeId::of::<$t>());
)*)
}
macro_rules! apply_macro_to_structs {
($macro_id:ident) => {
$macro_id! {
i8 i16 usize String
}
}
}
fn test_a() {
// expands one println per type!
print_structs! { i8 i16 usize String }
}
fn test_b() {
// expand using a macro
apply_macro_to_structs!(print_structs);
}
fn main() {
test_a();
test_b();
}
I'm searching for the syntax to do pattern matching with multiple cases in an if case statement.
The example would be this:
enum Gender {
case Male, Female, Transgender
}
let a = Gender.Male
Now I want to check, if a is .Male OR .Female. But I would like to avoid using switch for this. However the switch statement would be like this:
switch a {
case .Male, .Female:
// do something
}
Is it possible to write this with if case?
I would expect this, but it didn't work :(
if case .Male, .Female = a {
}
A simple array does the trick:
if [.Male, .Female].contains(a) {
print("Male or female")
} else {
print("Transgender")
}
I'm simply amazed at Swift's ability to infer type. Here, it gets that .Male and .Female are of type gender from a.
If you have an associated value, you can simply create a Bool variable like this
extension Gender {
var isMaleOrFemale: Bool {
switch self {
case .Male, .Female:
return true
default:
return false
}
}
And usage:
if a.isMaleOrFemale {
// Your code here
}
You should use a collection. In JavaScript I would write something like this:
if ([Gender.Male, Gender.Female].includes(actualGender))
console.log(actualGender);
Note that I have not a clue about swift, or how to do the same in that language, so here is a relevant answer in the topic: https://stackoverflow.com/a/25391725/607033 :D
EDIT: This is the Swift version:
if [.Male, .Female].contains(a) {
}
For pattern matching, what you describe will not work yet. You could do this in your case. But if it cannot be convert into a hashValue. Then this would not work either.
// Using Pattern Matching for more than one case.
if case 0...2 = a.hashValue {
print("Hello")
}
//Normal if else
if a == .Male || a == .Female {
print("Hello")
}
I need to set a variable depending on a condition. But since variables are immutable, I find myself in a sticky situation having to repeat code. What I'd like to do is:
def doSomething(x:Int):Int = {
if(x==1){
val player="Andy"
} else {
val player="Rob"
}
getSomeValue(player) // Another function
}
But the variable "player" is no longer in scope. Only way I see is to call the function "getSomeValue" in both the condition blocks, but that's not something I'd like to do. How do I get around this using immutable variables?
def doSomething(x:Int):Int = {
val player = if(x==1){
"Andy"
} else {
"Rob"
}
getSomeValue(player)
}
How do I call recursively an interface I am implementing from the implementation of this interface?
I am doing the following thing:
import io::*;
import to_str::*;
enum some_enum {
foo(~[some_enum]),
bar
}
impl to_str for some_enum {
fn to_str() -> str {
alt self {
bar { "bar" }
foo(nest) { "foo" + nest.to_str() } // this line
}
}
}
fn main() {
println(foo(~[bar,bar,bar]).to_str());
}
And it fails at compile time with
user#note ~/soft/mine/rust $ rustc example.rs && ./example
example.rs:13:32: 13:43 error: failed to find an implementation of interface core::to_str::to_str for some_enum
example.rs:13 foo(nest) { "foo" + nest.to_str() }
^~~~~~~~~~~
Of course I can do an FP-like thing:
foo(nest) { "foo" + nest.map(|x| { x.to_str() }).to_str() }
But why isn't the former case valid?
Seems like it can be solved with using impl of instead of impl.
impl without of acts like interface-less implementation, with no actual interface involved.
(confirming to http://dl.rust-lang.org/doc/tutorial.html#interface-less-implementations )