It is my understanding that a lambda function is a function that can be nameless. Wikipedia suggests that
var sqr = (x) => x * x;
print(sqr(5));
(where var is the same as dynamic Function(dynamic)), and
print(((x) => x * x)(5));
are both possible ways to write a lambda expression in Dart.
On some tutorials I read that code similar to
dynamic sqr(dynamic x) => x * x;
print(sqr(5));
is also considered to be a lambda expression, because it uses the arrow sign. It is my understanding however, that this is not a lambda expression, because this function will always need to be defined with a name. Am I correct?
dynamic sqr(dynamic x) => x * x; isn't an anonymous function because it has an identifier.
var sqr = (x) => x * x; is a lambda because (x) doesn't have an identifier.
=> is just shorthand for { return something; } and it doesn't necessarily mean you're writing an anonymous function. For example:
var sqr = (x){ return x * x;}; is still an anonymous function.
Related
I'm checking out some dart code and looking at this:
AppState.fromJson(Map<String, dynamic> json)
: cartItems = (json['cartItems'] as List)
.map((i) => new CartItem.fromJson(i as Map<String, dynamic>))
.toList();
What's the reasoning behind the colon?
Why is this different from a regular assignment?
You can find more info in the dart tour: https://dart.dev/guides/language/language-tour#classes
If the superclass doesn’t have an unnamed, no-argument constructor, then you must manually call one of the constructors in the superclass. Specify the superclass constructor after a colon (:), just before the constructor body (if any).
Besides invoking a superclass constructor, you can also initialize instance variables before the constructor body runs. Separate initializers with commas.
// Initializer list sets instance variables before
// the constructor body runs.
Point.fromJson(Map<String, num> json)
: x = json['x'],
y = json['y'] {
print('In Point.fromJson(): ($x, $y)');
}
During development, you can validate inputs by using assert in the initializer list.
Point.withAssert(this.x, this.y) : assert(x >= 0) {
print('In Point.withAssert(): ($x, $y)');
}
You can also use them to initialize the final variables:
class Point {
final num x;
final num y;
final num distanceFromOrigin;
Point(x, y)
: x = x,
y = y,
distanceFromOrigin = sqrt(x * x + y * y);
}
I am having issues creating a generic math class (here as very tiny example code a class of type Vector) that, however, is not limited to one single numerical data type for its values, but instead uses ^F as static resolved type parameter, and I expect it to be whatever the user uses to instanciate the class, such as int but also BigRational or MyCustomNumber, as long as it adheres to the constraints.
type Vector< ^F> (_values : ^F []) =
let values = _values
member inline __.Dimension = Array.length values
member inline __.Item with get i = values.[i + 1]
static member inline ( * ) (a: Vector< ^F>) (scalar: ^F) =
Vector< ^F>(Array.init (a.Dimension) (fun i -> values.[i] * scalar)
override inline __.ToString() = "{" + (values.ToString()) + "}" // <--- problem-line
My problem now with this code is, that I still don't know how to properly override the Object.ToString() method (same for how to implement IComparable, which I believe I could fix the same way).
Is this actually even possible?
Many thanks in advance!
Do not annotate the arithmetic operator's arguments with a type parameter, they will be inferred alright
Pass the arguments of the arithmetic operator as a tuple
Close the parenthesis in the implementation of the arithmetic operator
Replace the let-bound value values by a property
type Vector<'F> (_values : 'F[]) =
member val Values = _values
member inline me.Dimension = Array.length me.Values
member inline me.Item with get i = me.Values.[i + 1]
static member inline ( * ) (a: Vector<_>, scalar) =
Vector<_>(Array.init (a.Dimension) (fun i -> a.Values.[i] * scalar))
override me.ToString() = "{" + (me.Values.ToString()) + "}"
Is it possible to somehow create a pow function for measure types?
The pow function in f# only takes int as parameter, and then pow function in the Math class takes a float - but dosent allow float<cm>.
I first thought that:
let rec myPow(x:float<cm>,y:int) =
if y = 0 then x
else myPow(x*x, y - 1)
might work out, but its obvious that each time it come across the else line it will change the return type.
Any suggestions?
I don't think that is possible. You are asking the function to return <cm^2> in case the power is by 2 and <cm^3> in case of 3 and so on. Which makes the function to return different "types" based on the calculation which obviously not possible in a static type and type safe language. Unfortunately, I don't think units of measure can be made "generics" to try that to reach any further.
Your function can have only one static return type.
Ankur is correct - you cannot do this (without resorting to hacks that would break units).
Maybe a clearer description of the problem is that the type of pow function would depend on the value of the argument and F# doesn't allow you to do this. You could imagine this would work if were using just literals as the second argument, but it would become tricky if you used expressions:
pow a 3 // Assuming a = 1.0<cm>, the return type is float<cm ^ 3>
pow a n // Assuming a = 1.0<cm>, the return type is float<cm ^ n>
In the second case the value n would have to appear in the type!
You can use some nasty tricks (inspired by this Haskell article), but it becomes a bit crazy. Instead of using numeric literals, you'd use something like S(S(S(N))) to represent the number 3. This way, you can bring the number into the type. You probably don't want to do this, but here is an example:
[<Measure>] type cm
// Represents a number with units of measure powered to the
// number's value (e.g "(S (S O))" has type Num<cm, cm^3>)
type Num<[<Measure>] 'M, [<Measure>] 'N> =
| O_ of int * float<'N>
| S_ of int * Num<'M, 'N / 'M>
// Constructors that hide that simplify the creation
let O : Num<'M, 'M> = O_ (1, 0.0<_>)
let S n = match n with O_(i, _) | S_(i, _) -> S_(i + 1, n)
// Type-safe power function with units of measure
let pow (x:float<'M>) ((O_(i, _) | S_(i, _)):Num<'M, 'M 'N>) : float<'M 'N> =
// Unsafe hacky implementation, which is hidden
// from the user (for simplicity)
unbox ((float x) ** float i)
let res = pow 2.0<cm> (S (S O))
EDIT: I posted the source code to F# snippets, so that you can see the inferred types: http://fssnip.net/4H
As said, you cannot. If y is not known at compile-time, it's not possible to type check the expression in F# type system.
I suspect you'll use myPow only with a few small and known constants. In this case, you could use the following functions instead and keep static typing:
let inline pow2 (x: float<'a>) : float<'a^2> = pown (float x) 2 * 1.<_>
let inline pow3 (x: float<'a>) : float<'a^3> = pown (float x) 3 * 1.<_>
let inline pow4 (x: float<'a>) : float<'a^4> = pown (float x) 4 * 1.<_>
let inline pow5 (x: float<'a>) : float<'a^5> = pown (float x) 5 * 1.<_>
Is it possible to write a function to accept a tuple of variable length? I'm trying to write a method that can be called like this:
let a = sum(1,2)
let b = sum(1,2,3)
EDIT: Could it be interpreted as a function call with params? Or would the method need to be written in c#:
double sum(params object[] double) {
...
}
No - tuples are by definition not variable length, and to write a function like this you'd need something like template metaprogramming in C++ - and there isn't such a thing in F#; let inline won't help you there either.
Of course, if you take a list instead, it won't look that much different:
sum[1; 2]
sum[1; 2; 3]
#PavelMineav is right, you can't do it, but note that members can be overloaded, a la
type Foo() =
member this.sum(x,y) = x + y
member this.sum(x,y,z) = x + y + z
let foo = new Foo()
printfn "%d" (foo.sum(1,2))
printfn "%d" (foo.sum(1,2,3))
whereas let-bound functions cannot.
Is it possible to pass a reference to a function to another function in F#? Specifically, I'd like to pass lambda functions like
foo(fun x -> x ** 3)
More specifically, I need to know how I would refer to the passed function in a function that I wrote myself.
Yes, it is possible. The manual has this example:
> List.map (fun x -> x % 2 = 0) [1 .. 5];;
val it : bool list
= [false; true; false; true; false]
Functions are first class citizens in F#. You can therefore pass them around just like you want to.
If you have a function like this:
let myFunction f =
f 1 2 3
and f is function then the return value of myFunction is f applied to 1,2 and 3.
Passing a lambda function to another function works like this:
Suppose we have a trivial function of our own as follows:
let functionThatTakesaFunctionAndAList f l = List.map f l
Now you can pass a lambda function and a list to it:
functionThatTakesaFunctionAndAList (fun x -> x ** 3.0) [1.0;2.0;3.0]
Inside our own function functionThatTakesaFunctionAndAList you can just refer to the lambda function as f because you called your first parameter f.
The result of the function call is of course:
float list = [1.0; 8.0; 27.0]