Trouble implementing Summable - ceylon

I'm trying to implement classes DistanceCM and DistanceMM, and I want these to be summable interchangeably, as long as they both inherit from Distance.
However, I get this error:
"Error:(46, 76) ceylon: type parameter 'Other' of declaration
'Summable' has argument 'Distance' which is not assignable to upper
bound 'Summable' of 'Other'"
...which I can't decipher... The error message refers to this line in the code below:
shared actual Distance plus(Distance other)
This is the current code:
abstract class Distance() of DistanceMM | DistanceCM {
shared formal Distance multiplyScalar(Float scalar);
}
class DistanceMM(variable Float val) extends Distance() satisfies Summable<Distance>
{
shared Float distanceInMillimeters;
shared Float distanceInCentimeters;
switch (unit)
case (millimeter) {
distanceInMillimeters => val;
distanceInCentimeters => val / 10;
}
case (centimeter) {
distanceInMillimeters => val * 10;
distanceInCentimeters => val;
}
shared actual DistanceMM multiplyScalar(Float scalar) {
val = val * scalar;
return this;
}
shared actual Distance plus(Distance other) {
switch (other)
case (DistanceMM) {
return DistanceMM(val + other.distanceInMillimeters(), unit);
}
case (DistanceCM) {
return DistanceMM(val + other.distanceInCentimeters(), unit);
}
}
}
class DistanceCM(variable Float val) extends Distance() satisfies Summable<Distance>
{
shared Float distanceInMillimeters;
shared Float distanceInCentimeters;
switch (unit)
case (millimeter) {
distanceInMillimeters => val;
distanceInCentimeters => val / 10;
}
case (centimeter) {
distanceInMillimeters => val * 10;
distanceInCentimeters => val;
}
shared actual DistanceCM multiplyScalar(Float scalar) {
val = val * scalar;
return this;
}
// implementation missing
}

interface Summable<Other> of Other​ given Other satisfies Summable<Other>
Notice the constraint (the given clause). You're claiming that DistanceMM satisfies Summable<Distance>, but Distance doesn't satisfy the constraint on Other (Distance doesn't satisfy Summable<Distance>). Try this:
interface Distance of Centimeter | Millimeter satisfies Summable<Distance> {}
class Centimeter() satisfies Distance {
shared actual Distance plus(Distance other) => nothing;
}
class Millimeter() satisfies Distance {
shared actual Distance plus(Distance other) => nothing;
}

Related

detect an enum at runtime and stringify as keys

playground
I have a bunch of interfaces, at least 2-3 levels nested, where some of the leafs are numbers/strings, etc, but others are (numeric) enums.
I don't want to change this.
Now I want to "serialize" objects that implements my interfaces as JSON. Using JSON.stringify is good for almost all cases, but the enums, that are serialized with their (numerical) value.
I know that it's possible to pass a replacer function to JSON.stringify, but I'm stuck, as I'm not sure how to write a function that detect the structure of my object and replace the enum values with the appropriate names.
example:
enum E { X = 0, Y = 1, Z = 2 }
enum D { ALPHA = 1, BETA = 2, GAMMA = 3 }
interface C { e: E; }
interface B { c?: C; d?: D; }
interface A { b?: B; }
function replacer(this: any, key: string, value: any): any {
return value;
}
function stringify(obj: A): string {
return JSON.stringify(obj, replacer);
}
const expected = '{"b":{"c":{"e":"Y"},"d":"ALPHA"}}';
const recieved = stringify({ b: { c: { e: E.Y }, d: D.ALPHA } });
console.log(expected);
console.log(recieved);
console.log(expected === recieved);
It's not possible to automatically find out which enum was assigned to a field, not even with typescript's emitDecoratorMetadata option. That option can only tell you it's a Number and it will only be emitted on class fields that have other decorators on them.
The best solution you have is to manually add you own metadata. You can do that using reflect-metadata node module.
You'd have to find all enum fields on all of your classes and add metadata saying which enum should be used for serializing that field.
import 'reflect-metadata';
enum E
{
ALPHA = 1,
BETA = 2,
GAMMA = 3,
}
class C
{
// flag what to transform during serialization
#Reflect.metadata('serialization:type', E)
enumField: E;
// the rest will not be affected
number: number;
text: string;
}
This metadata could be added automatically if you can write an additonal step for your compiler, but that is not simple to do.
Then in your replacer you'll be able to check if the field was flagged with this matadata and if it is then you can replace the numeric value with the enum key.
const c = new C();
c.enumField= E.ALPHA;
c.number = 1;
c.text = 'Lorem ipsum';
function replacer(this: any, key: string, value: any): any
{
const enumForSerialization = Reflect.getMetadata('serialization:type', this, key);
return enumForSerialization ? enumForSerialization[value] ?? value : value;
}
function stringify(obj: any)
{
return JSON.stringify(obj, replacer);
}
console.log(stringify(c)); // {"enumField":"ALPHA","number":1,"text":"Lorem ipsum"}
This only works with classes, so you will have to replace your interfaces with classes and replace your plain objects with class instances, otherwise it will not be possible for you to know which interface/class the object represents.
If that is not possible for you then I have a much less reliable solution.
You still need to list all of the enum types for all of the fields of all of your interfaces.
This part could be automated by parsing your typescript source code and extracting the enum types for those enum fields and then saving it in a json file that you can load in runtime.
Then in the replacer you can guess the interface of an object by checking what are all of the fields on the this object and if they match an interface then you can apply enum types that you have listed for that interface.
Did you want something like this? It was the best I could think without using any reflection.
enum E { X = 0, Y = 1, Z = 2 }
enum D { ALPHA = 1, BETA = 2, GAMMA = 3 }
interface C { e: E; }
interface B { c?: C; d?: D; }
interface A { b?: B; }
function replacer(this: any, key: string, value: any): any {
switch(key) {
case 'e':
return E[value];
case 'd':
return D[value];
default:
return value;
}
}
function stringify(obj: A): string {
return JSON.stringify(obj, replacer);
}
const expected = '{"b":{"c":{"e":"Y"},"d":"ALPHA"}}';
const recieved = stringify({ b: { c: { e: E.Y }, d: D.ALPHA } });
console.log(expected);
console.log(recieved);
console.log(expected === recieved);
This solution assumes you know the structure of the object, just as you gave in the example.

libGDX unable to perform action

I have a Letter class like this:
class Letter : Label {
val char: Char
var interactable = true
constructor(char: Char) : super(""+char, H.letterStyle()) {
this.char = char
}
fun animateSelect() {
addAction(Actions.scaleTo(3.0f, 3.0f, 0.5f))
}
fun animateUnselect() {
addAction(Actions.scaleTo(3.0f, 3.0f, 0.5f))
}
}
In my touch listener, I have this:
override fun touchDown(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int): Boolean {
var currentInteractingLetter: Letter? = null
for (letter in letterList) {
if (letter.bound.contains(x, y)) {
currentInteractingLetter = letter
break
}
}
if (currentInteractingLetter == null) {
} else {
selectedLetters.add(currentInteractingLetter)
currentInteractingLetter.animateSelect()
currentInteractingLetter.interactable = false
}
return true
}
The logic is quite straightforward. When user touch any one of the letters, I will invoke animateSelect() function.
When I run it, animateSelect did get called, but there is no scaleUp effect. I have tried to clear all actions before addAction but still the same.
Labels don't directly support scaling.
The easy way to solve this is put the label in a Container, setTransform(true) on the Container, and add your scale action to the Container.
val container= Container<Label>().apply {
isTransform=true
actor=label // Set your Label to container
}
container.addAction(Actions.scaleTo(3.0f, 3.0f, 0.5f))

Defining the interface for a function using function properties

As you may know, functions in JavaScript can have properties as any object. For example (taken from the excellent JavaScript: The Definitive Guide, 6th ed, p. 178) computes a factorial using the function as memoization array:
function factorial(n: number): number {
if (isFinite(n) && n > 0 && n == Math.round(n)) {
if (!(n in factorial))
factorial[n] = n * factorial(n - 1);
return factorial[n];
}
else
return NaN;
}
factorial[1] = 1;
I tried defining the following interface:
interface Factorial {
(n: number) : number;
[ index: number ]: number;
}
But the compiler is telling me that Type '(n: number) => number' is not assignable to type 'Factorial'. Index signature is missing in type '(n: number) => number'.
I can't do the obvious thing and just define private index: number; inside the function, I'm stumped.
What you have is an example of hybrid types. You have to use type assertion to make sure the function complies with the interface:
let factorial = function (n: number): number {
if (isFinite(n) && n > 0 && n == Math.round(n)) {
if (!(n in factorial))
factorial[n] = n * factorial(n - 1);
return factorial[n];
}
else
return NaN;
} as Factorial;
factorial[1] = 1;

Typescript Interfaces: method that return a generic function

Someone know how can I define an interface for a class method like:
wrap(fn) {
return function(){
... // do something
fn()
}
}
I'm crashing my head around this, basically how can I define the type of a parameter (and a return value) to be function?
I'm supposing you wanted to return another function that have identical type of fn.
class Wrapper {
// generic for any fn, without handling parameter type
// a return type is not required: tsc infers from `return` statement.
wrap<T extends Function>(fn: T) {
return function () {
// NOTE this version does not handle types of parameters.
// you will have to use `arguments`
return fn();
} as any as T;
}
// generic for all unary fn
// we can have correct type of arg1 in this way
wrapF1<P1, R>(fn: (arg1: P1) => R) {
const wrapped = function (arg1: P1) {
return fn(arg1);
}
return wrapped;
}
// wrapF2, wrapF3, if you need more
}

c++11 : easiest way to create a function always returning true to use for a function argument

I want to use the following template member function
template <typename Entity>
class SomeCollection
{
// ....
template <typename Measure, typename Filter>
Entity maximalEntity(Measure&& measure, Filter&& requirement)
{
auto maxEntity = Entity();
auto maxValue = -std::numeric_limits<double>::infinity();
for (auto ent /* some iteration method*/)
{
auto measurement = measure(ent);
if (requirement(ent) && measurement > maxValue)
std::tie(maxEntity, maxValue) = std::make_tuple { ent, measurement };
}
return maxEntity;
}
// ...
};
What is the best way to call this function from client code without Filter requirement (to just have the maximal element) ?
The best I can come up with is:
class Something;
double measure(Something&);
SomeCollection<Something> collection;
auto maximum = collection.maximalEntity(measure, [](const Something&) { return true; });
But I guess this lambda function could be improved no ?
Not sure how the lambda can be improved, but you could define a generic lambda that given any input would return always true (which could also be used here):
auto always_true = [](auto&&...) { return true; };
and you would use it as:
auto maximum = collection.maximalEntity(measure, always_true);
Live demo
An equivalent implementation for C++11 is the following:
struct always_true {
template<typename... Args>
bool operator()(Args&&...) const noexcept {
return true;
}
};
which would then be used as:
auto maximum = collection.maximalEntity(measure, always_true{});
Live demo
You could create a lambda which returns true and set it as default parameter.
auto true_filter = [](const Something& arg){ return true; };
//auto true_filter = [](auto&& arg){ return true; }; if you have c++14
...
template <typename Measure, typename Filter = decltype(true_filter)>
Entity maximalEntity(Measure&& measure, Filter requirement = true_filter)
{
...
auto maximum = collection.maximalEntity(measure);
Note the Filter has changed from Filter&&. I have not get it to work with rvalue refs here.
Though having it explicitly stated is probably better design. Just an option to have it "shorter"
C++14:
template<class T>
auto always() {
return [](auto&&...)->T{return {};};
};
or in C++11:
template<class T>
struct always {
template<class...Args>
T operator()(Args&&...)const{ return {}; }
};
use:
collection.maximalEntity(measure, always<std::true_type>());
this has the advantage that the truth of the lambda involved is encoded in the type system, which makes it marginally easier for compilers to optimize its behavior.
This also lets you do always<std::false_type> or always<std::integral_constant<int, 42>>() etc.
In C++17 I'd do:
template<auto x>
auto always() {
return [](auto&&)->std::integral_constant<decltype(x), x>
{ return {}; };
}
which permits always<true>() and always<42>() (and maybe always<nullptr>()?).