Thread overview
Range to Nullable conversion
Jun 10, 2022
Antonio
Jun 10, 2022
Ali Çehreli
Jun 10, 2022
Antonio
Jun 10, 2022
Paul Backus
Jun 10, 2022
Antonio
June 10, 2022

Is there any alternative to range front that returns a Nullable (i.e. frontAsMonad or frontAsNullable)?

I'm using Vibe.d and Nullable is the standard way to return an optional element:

  @safe Nullable!Item getItem(int _id)
  {
    import std.algorithm : filter;

    with (items.filter!(item => item.id == _id))
    {
      if (empty)
        return Nullable!Item.init;
      else
        return front.nullable;
    }
  }

Can this code be written as a simple expression? (without having to write helper methods).

June 10, 2022
On 6/10/22 10:22, Antonio wrote:
> Is there any alternative to ***range front*** that returns a Nullable
> (i.e. **frontAsMonad** or **frontAsNullable**)?

import std;

// Spelling? :)
auto nullablelize(R)(R range) {
  alias E = Nullable!(ElementType!R);

  struct Nullablelize {
    enum empty = false;

    auto front() {
      if (range.empty) {
        return E();

      } else {
        return E(range.front);
      }
    }

    void popFront() {
      if (!range.empty) {
        range.popFront();
      }
    }

    // Other range algorithms like save(), etc. here
  }

  return Nullablelize();
}

void main() {
  // Wow! We can take 10 elements without error. :)
  writeln(iota(5)
          .filter!(i => i % 2)
          .nullablelize
          .take(10));
}

Ali

June 10, 2022

On Friday, 10 June 2022 at 17:22:53 UTC, Antonio wrote:

>

Can this code be written as a simple expression? (without having to write helper methods).

import std.range, std.typecons;

Nullable!(ElementType!R) maybeFront(R)(auto ref R r)
    if (isInputRange!R)
{
    if (r.empty)
        return typeof(return)();
    else
        return nullable(r.front);
}

unittest
{
    int[] a = [1, 2, 3];
    int[] b;

    assert(a.maybeFront == nullable(1));
    assert(b.maybeFront.isNull);
}
June 10, 2022
On Friday, 10 June 2022 at 17:37:13 UTC, Ali Çehreli wrote:
> On 6/10/22 10:22, Antonio wrote:
> > Is there any alternative to ***range front*** that returns a
> Nullable
> > (i.e. **frontAsMonad** or **frontAsNullable**)?
>
> import std;
>
> // Spelling? :)
> auto nullablelize(R)(R range) {
>   ...
> }
>
> void main() {
>   // Wow! We can take 10 elements without error. :)
>   writeln(iota(5)
>           .filter!(i => i % 2)
>           .nullablelize
>           .take(10));
> }
>
> Ali

That's cheating :-p... you used a helper method+structure.

Nice example, Thank you Ali.
June 10, 2022

On Friday, 10 June 2022 at 18:00:20 UTC, Paul Backus wrote:

>

On Friday, 10 June 2022 at 17:22:53 UTC, Antonio wrote:

>

Can this code be written as a simple expression? (without having to write helper methods).

import std.range, std.typecons;

Nullable!(ElementType!R) maybeFront(R)(auto ref R r)
    if (isInputRange!R)
{
    if (r.empty)
        return typeof(return)();
    else
        return nullable(r.front);
}

unittest
{
    int[] a = [1, 2, 3];
    int[] b;

    assert(a.maybeFront == nullable(1));
    assert(b.maybeFront.isNull);
}

Nice (and simple) helper method.

Thank you Paul