Comment #0 by bearophile_hugs — 2014-04-29T11:47:07Z
I suggest to add to Phobos a simple function to improve the usage of Nullable.
This simple code shows a function foo that returns a Nullable!int, and a function twoTimes that duplicates a Nullable!int:
import std.typecons: Nullable;
Nullable!int foo(in bool b) {
return b ?
typeof(return)(1) :
typeof(return)();
}
Nullable!int twoTimes(in Nullable!int x) {
return x.isNull ?
typeof(return)(1) :
typeof(return)(x.get * 2);
}
void main() {
immutable result = true.foo.twoTimes;
}
But in general you don't want to write a function twoTimes that way, you prefer a simpler code:
int twoTimes(in int x) { return x * 2; }
This causes the calling code inside main() to become more complex and more bug-prone (also if you want twoTimes2 to be immutable the code becomes even more complex):
import std.typecons: Nullable;
Nullable!int foo(in bool b) {
return b ?
typeof(return)(1) :
typeof(return)();
}
int twoTimes(in int x) { return x * 2; }
void main() {
auto temp = true.foo;
Nullable!int result;
if (!temp.isNull)
result = temp.get.twoTimes;
}
So I suggest to add to Phobos a function like this "Maybe" (other names are possible for such function), this is just a basic implementation:
import std.typecons: Nullable;
import std.traits: ReturnType, ParameterTypeTuple, Unqual;
Nullable!(ReturnType!F) Maybe(alias F, T)(Nullable!T x)
if (ParameterTypeTuple!F.length == 1 &&
is(Unqual!(ParameterTypeTuple!F[0]) == T)) {
if (x.isNull)
return typeof(return)();
else
return typeof(return)(F(x.get));
}
Nullable!int foo(in bool b) {
return b ?
typeof(return)(1) :
typeof(return)();
}
int twoTimes(in int x) { return x * 2; }
void main() {
immutable temp = true.foo.Maybe!twoTimes;
}
This basic implementation of "Maybe" is limited to single-argument functions. But a better implemented Try should accept any number of arguments, and accept both Nullable and not-Nullable arguments. "Maybe" returns a null Nullable if one or more arguments are a null Nullable:
Maybe!myFunc(nullable1, x)
Notes:
- This Maybe isn't the Maybe of Haskell.
- This Maybe is related to a similar function that returns a null Nullable if the given function throws a specified exception. But they should be distinct functions.
- Some languages have a built-in operator ".?" to handle safe null chaining. So instead of "true.foo.Maybe!twoTimes" you write something like "true.foo.?twoTimes".
Comment #1 by monkeyworks12 — 2014-10-20T05:30:11Z
Isn't this pretty much the same as Haskell's fmap? It'd be nice to have something generic like this that worked on a wide variety of ranges (Nullable would have to be made a range, or have a toRange function or something).