www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12679] New: std.typecons.Maybe

https://issues.dlang.org/show_bug.cgi?id=12679

          Issue ID: 12679
           Summary: std.typecons.Maybe
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: Phobos
          Assignee: nobody puremagic.com
          Reporter: bearophile_hugs eml.cc

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".

--
Apr 29 2014