How do I inject an anonymous function directly into an enum - flutter

For Dart 2.17, we can use constructors in enum similarly to how we do with classes.
I am trying to insert an anonymous function inside of an enum directly.
here is code that works but doesn't do exactly what I'd like it to do.
int _add(int a, int b) => a + b;
int _sub(int a, int b) => a - b;
int _mul(int a, int b) => a * b;
double _div(int a, int b) => a / b;
enum MyEnum {
addition(_add),
subtract(_sub),
multiplication(_mul),
division(_div);
final Function fx;
const MyEnum(this.fx);
}
void main() {
var fun = MyEnum.addition;
print(fun.fx(1, 2));
fun = MyEnum.subtract;
print(fun.fx(1, 2));
fun = MyEnum.multiplication;
print(fun.fx(1, 2));
fun = MyEnum.division;
print(fun.fx(1, 2));
}
Instead of making a function somewhere else in the code, as the _add, _sub, _mul, _div, I would like to directly insert an anonymous function into the enum, like in the following code (please note that the following code does not work).
What I'd like to do
enum MyEnum {
// I'd like to insert an anonymous function instead.
addition((int a, int b) => _add(a, b)),
subtract((int a, int b) => a - b),
multiplication(int a, int b) => a * b),
division((int a, int b) => a / b;);
final Function fx;
const MyEnum(this.fx);
}
Is it possible? Would anyone be able to show me how to do this? I cannot figure out what I am doing wrong.

One point of Dart 2.17 is that you no longer need to use extensions. The following code, which incorporates the features of Dart 2.17, is how I solved it. Though this certainly is not as elegant nor satisfying as I would have hoped it would have been in my original post.
enum MyEnum {
addition(),
subtract(),
multiplication(),
division();
Function fx() {
switch (this) {
case addition:
return (int a, int b) => a + b;
case subtract:
return (int a, int b) => a - b;
case multiplication:
return (int a, int b) => a * b;
case division:
return (int a, int b) => a / b;
default:
throw Exception('Unknown operation');
}
}
const MyEnum();
}
void main() {
var fun = MyEnum.addition;
print(fun.fx()(1, 2));
fun = MyEnum.subtract;
print(fun.fx()(1, 2));
fun = MyEnum.multiplication;
print(fun.fx()(1, 2));
fun = MyEnum.division;
print(fun.fx()(1, 2));
}

Have you tried extensions? I'm not sure you'll be able to do everything you want (as happened to me), but they almost got the job done. Sometimes I just have to invoke the extension instead of the enum, probably when I put some static method on the extension (like calling SexExt.staticMethod() instead of Sex.staticMethod), but I find them pretty useful.
enum Sex { MALE, FEMALE }
extension SexExt on Sex {
String getText() {
switch (this) {
case Sex.MALE:
return "Maschio";
case Sex.FEMALE:
return "Femmina";
}
}
String getShortText() {
switch (this) {
case Sex.MALE:
return "M";
case Sex.FEMALE:
return "F";
}
}
}

Related

Problem concerning null safety in functions

I have this function called add which adds two numbers and returns the result in dart.
void main() {
int step1Result = add(n1: 5, n2: 9);
int step2Result = multiply(step1Result, 5);
double finalResult = step2Result / 3;
print(finalResult);
}
int add({int n1, int n2}){
return n1 + n2;
}
but it keeps on throwing the error that n1 and n2 can't have a value of 'null' because of its type, but the implicit default value is 'null'.
I tried adding the ? mark but the it threw another error saying
The operator '+' can't be unconditionally invoked because the receiver can be 'null'.
The error comes from the declaration of your add function:
Here
int add({int n1, int n2}){
// ...
}
Here you're declaring two optional parameters to the functions.
But n1 and n2 are int and not int?
To fix this issue, you can either transform your function to take int? types.
Or to add the required keyword to tell that the function will only work if both parameters will be given.
void main() {
int step1Result = add(n1: 5, n2: 9);
int step2Result = multiply(step1Result, 5);
double finalResult = step2Result / 3;
print(finalResult);
}
int add({required int n1,required int n2}){
return n1 + n2;
}
You can learn more about null-safety syntax and principles on the official documentation: https://flutter.dev/docs/null-safety.
https://api.flutter.dev/flutter/material/DropdownButton-class.html.

Swift functions inside a var

I am learning Swift, and want to know how to add functions to a var,
here the JS example...
function suma (a, b){
return a + b
}
console.log("sua suma::", suma(2,3))
function multiplica (a, b){
return a * b
}
console.log("sua multiplik::", multiplica(2,3))
const operations = {
suma,
multiplica
}
console.log ("sum of first class::", operations.suma(2,3))
console.log ("mult of first class::", operations.multiplica(2,3))
so how do I achieve the same on Swift?
Here what I have tried:
import Foundation
func suma(a:Int, b:Int) -> Int {
return a + b
}
func multiplica(a:Int, b:Int) -> Int {
return a * b
}
print("sua suma", suma(a: 2, b: 3))
print("sua multiplica", multiplica(a: 2, b: 3))
var operations = {
suma
multiplica
}
print("sua operatio", operations.suma(a: 2, b: 3)
So how to edit the Swift code to call the function inside operations?
Cheers
You could use a tuple for this:
let operations = (
suma: suma
multiplica: multiplica
)
print("sua operatio", operations.suma(2, 3)
Note that the names are duplicated. The one before the : is just a label so that you can refer to it with a name, and the one after the : actually refers to the function.
I would advise against writing Swift code in a JS style. You should not group functions together like this. Write a class/struct instead, and declare the functions in there. Use static where necessary.
As Sweeper mentioned in his answer the Swift equivalent of the JS code would probably be a class with static functions.
class Operations {
static func suma(a:Int, b:Int) -> Int {
return a + b
}
static func multiplica(a:Int, b:Int) -> Int {
return a * b
}
}
You would call the functions like this
print("sua operatio \(Operations.suma(a: 2, b: 3))")

Create Class Object within Method of Another Class C++

I am new to C++. How do you create a method within one class which initializes an object within another class with specified parameters? Something like the following.
class A {
public:
double X;
double Y;
A(double a, double b) {
X = a;
Y = b;
};
class B {
public:
A f(double a, double b) {
//Initialize an object of type A using parameters specified.
};
};
I want to use the object of type A later so, presumably, I would need to use the new operator within f. Thanks in advance.
Try this:
class B {
public:
A* f(double a, double b) { return new A(a, b); };
};
Although you could just as easily do new A(a,b) anywhere you wanted to do B.f(a,b).

Codewars - Swift Solution (Multiply Function)

func multiply(_ a: Double, _ b: Double) -> Double {
a * b
}
What's wrong with this part of code? I am having trouble trying to figure it out.
Edit: in newer versions of Swift, OP's code works too, since return is no longer needed if there is only one expression in the body of a funcion/variable. Details here.
You are not doing anything with the result.
-> Double indicates that this function should return a Double. For that, you should use the return keyword:
func multiply(_ a: Double, _ b: Double) -> Double {
return a * b
}
Try this
public class Multiply
{
public double multiply(double a, double b)
{ return a * b;}
}
public class Multiply
{
public static Double multiply(Double a, Double b)
{
return a * b;
}
}

Generic factory method and type inference

I have the following class with a generic factory method:
final class Something<T> {
let value: T
init(initial: T) {
value = initial
}
}
extension Something {
class func zip<A, B>(_ a: A, _ b: B) -> Something<(A, B)> {
let initial = (a, b)
return Something<(A, B)>(initial: initial)
}
}
How come I can’t call zip without explicitly specifying the return type?
// ERROR: Cannot invoke `zip` with an argument list of type `(Int, Int)`
let y = Something.zip(1, 2)
// OK: Works but it’s unacceptable to require this on caller's side
let x = Something<(Int, Int)>.zip(1, 2)
Thank you for your time!
The reason you're seeing this is that there's nothing in this call:
let y = Something.zip(1, 2)
That tells Swift what T should be.
Your call implicitly specifies what A and B should be, and specifies the method should return Something<A, B>. But that Something<A, B> is not connected to Something<T>.
In fact, nothing at all in your call is connected to T; T is left unspecified, so it could be anything. I mean that literally—you can actually put (nearly) any random type in the angle brackets after Something and it'll work exactly the same:
let y = Something<UICollectionViewDelegateFlowLayout>.zip(1, 2)
What you would really like to do is somehow specify that T has to be a tuple and the two parameters are of the same types as the tuple's elements. Unfortunately, Swift doesn't currently have the features needed to properly do that. If the language were more sophisticated, you could say something like this:
extension<A, B> Something where T == (A, B) {
class func zip(a: A, _ b: B) -> Something {
let initial = (a, b)
return Something(initial: initial)
}
}
But for now, you'll have to make do with this horrible hack, which works by meaninglessly reusing the T type parameter so that it's no longer at loose ends:
extension Something {
class func zip<B>(a: T, _ b: B) -> Something<(T, B)> {
let initial = (a, b)
return Something<(T, B)>(initial: initial)
}
}
In short explanation, you use generics not correct. It's not realtime feature, it's precompile thing. If you need to make abstract class from generic input values, see and do like this:
class Abstract<T> {
init(value: T) {
print("inputed value: \(value)")
}
}
class Something {
class func zip<A, B>(value: A, value2: B) -> Abstract<(A, B)> {
print("Something.zip", value, value2)
return Abstract<(A, B)>(value: (value, value2))
}
}
Something.zip(5, value2: 40) // "inputed value: (5, 40)"
T simply isn't related to A and B in that way and so can't be inferred.
Eg.
let z = Something<(String, String)>.zip(1, 2)
let z2 = Something<AnyObject>.zip(1, 2)
work just fine to return a Something<(Int, Int)>
You can introduce type inference for your case like this:
final class Something<T> {
let value: T
init(initial: T) {
value = initial
}
class func zip<A, B>(_ a: A, _ b: B) -> Something<T> where T == (A, B) {
let initial = (a, b)
return Something<(A, B)>(initial: initial)
}
}
let y = Something.zip(1, 2) //works