We have 2 functions
- identity just returns its first argument
- test accepts a Nat → Nat function and calls it
Why cannot we use identity as an argument for the test function?
I am getting “expression of type … cannot produce expected type” error.
We have 2 functions
Why cannot we use identity as an argument for the test function?
I am getting “expression of type … cannot produce expected type” error.
I cant speak to the technical reason but you can get around it with another function
ignore test(func (n: Nat) = identity<Nat>(n));
https://m7sm4-2iaaa-aaaab-qabra-cai.ic0.app/?tag=1307026162
It is a good thing there is a way to get around it, yet still I hope we’d be able to do it the correct way one day
I think it works in the example you shared because we explicitly specify <Nat>
parameter
On the other hand, if we don’t call the identity function (just pass it around, as in my example), there is no way to explicitly specify the parameter
@claudio What do you think about the error above? Are there any plans to support it in the future?
Do you mean you want to be able to write:
ignore test(identity<Nat>);
?
Hopefully, It works even without <Nat>
. But identity<Nat>
would be a good workaround
I sympathize with this and it is definitely what users expect from ML-like languages (SML, OCaml, F#, Haskell).
Unfortunately, it might actually be problematic for the subtyping we use in Motoko, i.e. it is possible it makes subtyping undecidable. Would need to look at the literature to be sure.
It is strange that inline function works here even without specifying parameter type and return type
ignore test(func(n) = identity(n));
(modified @Gekctek’s suggestion)
but we still can not pass a function with type parameters directly
Type instantiation is part of function call syntax in Motoko, it does not exist as a stand-alone thing – dually, you cannot introduce generic parameters without function parameters, and there are no generic types independent from functions. It behaves similar to most conventional languages rather than ML-style ones in that regard.
There are a few technical reasons for this, which have to do with compilation, side effects, and the lack of partial application in Motoko. FWIW, I don’t think subtyping poses a problem here, it primarily comes down to a form of currying (with runtime type passing, it literally is), but Motoko does not support that either.
@ZhenyaUsenko, this is no different from regular parameters, where you cannot pass a two-argument function f
as test(f(3))
, but have to write test(func(n) = f(3, n))
instead.