On Saturday, 26 July 2025 at 23:08:35 UTC, luafyn wrote:
Why doesn't this work?
```d
import std;
struct Optional(T)
{
T value;
bool hasValue;
}
auto map(alias fn, T)(Optional!T m)
{
alias U = ReturnType!fn;
In this case, an untyped function literal (`it => 123`) is
actually a template function (pointer) and there is no way for
the compiler to infer what the type of `fn` should be for
`ReturnType!fn`.
monkyyy's solution is fine, though I'd probably write this:
```d
alias U = typeof(fn(m.value));
```
if (m.hasValue) {
return Optional!U(fn(m.value), true);
} else {
return Optional!U();
}
}
void main()
{
auto x = Optional!string("123", true);
auto y = x.map!(it => 123);
writeln(y);
}
```
Error:
```d
onlineapp.d(11): Error: template instance
`onlineapp.main.ReturnType!(__lambda_L23_C21)` does not match
template declaration `ReturnType(alias func)`
with `func = __lambda_L23_C21(__T1)(it)`
must satisfy the following constraint:
` isCallable!func`
alias U = ReturnType!fn;
^
onlineapp.d(23): Error: template instance
`onlineapp.main.map!((it) => 123, string)` error instantiating
auto y = x.map!(it => 123);
^
```
This error message makes noooooo sense to me. At all. It's
gibberish. How is a lambda not callable?! This is really
frustrating, as something that works *absolutely trivially* in
any other language.
The problem is `isCallable` (in the general case) cannot detect
template functions that are instantiable with IFTI. The docs for
it were updated earlier in the month but are currently only on
the prerelease version:
https://dlang.org/phobos-prerelease/std_traits.html#isCallable
In Phobos 3 `isCallable` will likely be replaced. I think when it
was made to support some templates with `!()`, that muddied the
waters. It would make sense IMO (possibly with another name) if
it only worked with functions, delegates and types with `opCall`.
Also Steven Schveighoffer [has
proposed](https://forum.dlang.org/post/dtxmsbsrxtguvyzpp...@forum.dlang.org) `__traits(canCall, expression)` which if implemented would be a much better alternative to using `isCallable` in a template constraint.
It's something that I've ran against with D time and time
again: I get an inscrutable error or problem that is only
solved by “just” knowing the right incantation to use, anytime
I try to do something even slightly unorthodox, and it makes D
really annoying to use if you’re new to it.
It's interesting to see problems like that, there may be ways to
improve the language/compiler error messages/Phobos or the docs
to help with these.