I'm playing with D2 at the moment, I would like to write some simple program but i'm stuck with operator cast overload...I have a Vector class that can be cast to Normal :
class Vector {
public float x,y,z;
this(in float x, in float y, in float z){
this.x = x;
this.y = y;
this.z = z;
}
//..............
Normal opCast(T)() if (is(T == Normal)){
return new Normal(this.x,this.y,this.z);
}
}
If i write something like
immutable Vector v = cast(immutable(Vector))new Vector(0F, 0F, 0F);
the compiler complains that :
"template instance opCast!(immutable(Vector)) does not match template declaration opCast(T) if (is(T == Normal))"
If I omit the cast:
immutable Vector v = new Vector(0F,0F,0F);
the message changes, but the program does not compile:
"cannot implicitly convert expression (new Vector(0F,0F,0F)) of type Vector to immutable(Vector)"
If I omit the cast operator overload in the Vector class all compile just fine.
Put in a different way...How can I assign or cast an instance to an immutable 'var'?
you should not overload opCast normally.
commonly methods named toTypename are used for object that knows how to convert itself to another.
Normal toNormal () { return new Normal (x, y, z); }
You have two solutions:
A pretty solution is what Trass3r already mentioned in his comment: Treat immmutable(Vector) as its own data type (it is), and call its constructor.
A somewhat uglier solution is to use assumeUnique() on the object you want to cast. I think you might need to import a library (std.exception, if I'm not wrong).
Related
I am writing a custom mixin routine, it accepts varags of objects:
type HasIndex = {[key:string]:any};
// type RetType = ?
const mixinAll = (...v: HasIndex[]): RetType => {
return v.reduce((a,b) => doMixing(a,b,new Set()), {});
});
so my question is - how can I represent the return value for mixinAll? Is there a way to represent a mixin type with TypeScript? Very similar to doing the same for Object.assign.
If you look at the definition for Object.assign, that pretty much answers the question:
interface ObjectConstructor {
assign<T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W;
}
in short, use the & operator to create an intersection type - unfortunately can't seem to create something finer-grained than that.
Scala.js facade for a native JS types can look like this (from Three.js facade):
#js.native
#JSName("THREE.Vector3")
class Vector3 extends Vector {
def this(x: Double = js.native, y: Double = js.native, z: Double = js.native) = this()
var x: Double = js.native
var y: Double = js.native
var z: Double = js.native
/* ... */
}
The corresponding Javascript definition of a function constructing Vector3 is:
function Vector3( x, y, z ) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
I have read docs about creating Scala.js facades, however constructors are only briefly mentioned there. The code from the facade works fine in real code, however I am unsure if the definition is correct and why and how it works.
the facade lets no argument constructor exist.
the constructor with arguments just calls a no argument constructor. Still the object seems to be constructed fine, with the member set to the values passed.
the constructor uses js.native as default value for all arguments. Should all facades define constructors this way?
Esp. the second point is confusing to me. How can this be working? In all three cases I would like to know what JS code is generated for the constructor and why.
One could also imagine a different way how to write the facade. Would that be more correct?
class Vector3(var x: Double = js.native, var y: Double = js.native, var z: Double = js.native) extends Vector {
/* ... */
}
The definition is correct. The rules of facades for JavaScript constructors are quite simply stated: when encountering a call such as
new C(arg1, ..., argN)
and C is a JavaScript class, this translates to
new Cconstr(arg1, ..., argN)
where Cconstr is the result of evaluating js.constructorOf[C]. For a native JavaScript class, js.constructorOf[C] looks up the name of C in the global scope (or applies #JSName or #JSImport rules). Concretely, in your example, a call such as
new Vector3(3, 4, 5)
translates to
new <global>.THREE.Vector3(3, 4, 5)
Note, in particular, that the body of the constructor definitions is completely irrelevant, since the call site directly calls JavaScript code in the Three.js library. Hence, the fact that the 3-arg constructor calls the 0-arg constructor and ignores its arguments is simply disregarded by the semantic rules. The call is necessary to comply with Scala's type checking rules, but is semantically irrelevant.
Similarly, the actual value of default parameter values are semantically irrelevant. Their presence makes the parameters optional, but their value is otherwise ignored by the compiler. A call such as
new Vector3(3)
translates in JavaScript to
new <global>.THREE.Vector3(3)
in which the y and z parameters are altogether not given, leaving to JavaScript to decide what to do with them.
Finally, your alternative definition:
class Vector3(var x: Double = js.native, var y: Double = js.native, var z: Double = js.native)
is just equally valid. It doesn't have an explicit 0-arg constructor, but it can also be "accessed" by giving 0 argument to the constructor, which has 3 optional parameters anyway. This definition is certainly more concise, though, and looks a bit more Scala-esque, so I would personally define it that way. But it is not any more correct than the initial one.
I'm trying to define a generic add function to numeric values:
def add[A](x:A, y:A): A = {
x + y
}
console:16: error: type mismatch;
found : A
required: String
x + y
^
What's the compiler complaining about?
Some of the stuff I've googled does not quite make sense to me at this moment.
Since you define A with no boundaries and no extra information, it could be any type, and not any Scala type has a + method - so this can't compile.
The error message is a result of the compiler's attempt to implicitly convert x into a String (because String has a + method, and every type can be converted to string using toString), but then it fails because y isn't a string.
To create a method for all numeric types, you can use the Numeric type:
def add[A](x:A, y:A)(implicit n: Numeric[A]): A = {
n.plus(x, y)
}
add(1, 3)
add(1.4, 3.5)
EDIT: or an equivalent syntax:
def add[A: Numeric](x:A, y:A): A = {
implicitly[Numeric[A]].plus(x, y)
}
To be able to do something like this the compiler needs to know that A has a method
def +(a: A): A
so ideally you would want to do something like
def add[A :< Numeric](x:A, y:A): A = { ...
but you can't because the numeric types in Scala have no common super type (they extend AnyVal). Look here for a related question.
I am new to scala .
I want to understand the syntax of this below code
object PlainSimple {
def main(args:Array[String])
{
val m = add(5)
println(m(3))
}
def add(x:Int):Int=>Int =
{
y=>y+x
}
}
My question is where are we saying that the add function is returning another function?
What does Int=>Int mean?
Inside the add function what is called y? Why are we using it without declaring it anywhere?
What do need to do if want multiples line inside add method?
My question is Where are we saying that the add function is returning another function?
Right here
def add(x: Int): Int => Int = y => y + x
Int => Int is a function type. That's just syntactic sugar, but you can also write it as
def add(x:Int): Function1[Int, Int] = y => y + x
Now, what is y? y => y + x is a lambda, i.e. an anonymous function. This lambda takes one parameter that we're now referring to as y.
Here's a good reference on anonymous functions in scala and their syntax: http://docs.scala-lang.org/tutorials/tour/anonymous-function-syntax.html
In order to have multiple lines inside the method just use braces
def add(x:Int): Function1[Int, Int] = { y =>
println("whaveter")
y + x
}
My question is Where are we saying that the add function is returning another function?
What is Int=>Int means?
T => U as a type means "a function that takes a T and returns an U". So when we write : Int => Int at the end of the function signature, we say "this function returns a function from Int to Int".
Inside the add function what is called y ? Why are we using it without declaring it anywhere?
As an expression x => body (or (x,y,z) => body for multiple parameters) is a function literal, that is it defines an anonymous function whose parameter is named x and whose body is body. So we are declaring the parameter x by writing its name of the left side of the =>.
What do need to do if want multiples line inside add method?
You can put anything to the right of => that you could also put to the right of = when defining a method using def. So if you want your function's body to consist of multiple statements, you can use braces just like with a regular method definition:
y => {
val z = y+x
z*2
}
Let's define a trait with an abstract class
object Outer {
trait X {
type T
val empty: T
}
Now we can make an instance of it:
val x = new X {
type T = Int
val empty = 42
}
Scala now recognizes, that x.empty is an Int:
def xEmptyIsInt = x.empty: Int
Now, let's define an other class
case class Y(x: X) extends X {
type T = x.T
val empty = x.empty
}
and make an instance of it
val y = Y(x)
But now Scala, isn't able to infer that y.empty is of type Int. The following
def yEmptyIsInt = y.empty: Int
now produces an error message:
error: type mismatch;
found : y.x.T
required: Int
y.empty : Int
Why is this the case? Is this a scala bug?
We can mitigate this issue by introducing a parameters to the case class:
case class Z[U](x: X { type T = U }) extends X {
type T = U
val empty = x.empty
}
Then it works again
val z = Z(x)
def zEmptyIsInt: Int = z.empty
But we always have to mention all the types inside X at call-site. This ideally should be an implementation detail which leads to the following approach:
case class A[U <: X](z: U) extends X {
type T = z.T
val empty = z.empty
}
This also mitigates the issue
val a = A(x)
def aEmptyIsInt: Int = a.empty
}
So, to summarize, my questions are the following: Why does the simple case doesn't work? Is this a valid workaround? What other problems might come up when we follow one of the two workaround approaches? Is there a better approach?
You've re-used x for different things, so from here on I'll call the object instantiated by val x "instance x" and the x: X used in class Y "parameter x".
"Instance x" is an anonymous subclass of trait X with concrete members overriding trait X's abstract members. As a subclass of X you can pass it to the constructor for case class Y and it will be accepted happily, since as a subclass it is an X.
It seems to me you expect that case class Y will then check at runtime to see if the instance of X it is passed has overridden X's members, and generate an instance of Y whose members have different types depending on what was passed in.
This is emphatically not how Scala works, and would pretty much defeat the purpose of its (static) type system. For example, you wouldn't be able to do anything useful with Y.empty without runtime reflection since it could have any type at all, and at that point you're better off just using a dynamic type system. If you want the benefits of parametricity, free theorems, not needing reflection, etc. then you have to stick to statically determined types (with a small exception for pattern matching). And that's what Scala does here.
What actually happens is that you've told Y's constructor that parameter x is an X, and so the compiler statically determines that x.empty, has the type of X.empty, which is abstract type T. Scala's inference isn't failing; your types are actually mismatched.
Separately, this doesn't really have anything to do with path-dependent types. Here is a good walkthrough, but in short, path-dependent types are bound to their parent's instance, not determined dynamically at runtime.