Thread overview
std.sumtyp and option ?
Jun 29, 2023
kiriakov
Jun 29, 2023
Paul Backus
Jun 29, 2023
kiriakov
Jun 29, 2023
jmh530
June 29, 2023

How to create option type over std.sumtype ?

enum None;
struct Some(T) { T x; }
alias Option = SumType!(Some!T, None);

I get
Error: undefined identifier T

June 29, 2023

On Thursday, 29 June 2023 at 14:18:05 UTC, kiriakov wrote:

>

How to create option type over std.sumtype ?

enum None;
struct Some(T) { T x; }
alias Option = SumType!(Some!T, None);

I get
Error: undefined identifier T

Looks like you meant to type

alias Option(T) = SumType!(Some!T, None);

Unfortunately, due to issue 1807, this is not a good way to define an Option type. If you try to use it as a function parameter, you will get confusing error messages.

import std.sumtype;

struct None {}
struct Some(T) { T value; }
alias Option(T) = SumType!(None, Some!T);

bool isNone(T)(Option!T opt)
{
    return opt.match!(
        (Some!T _) => false,
        (None _) => true
    );
}

unittest
{
    Option!int x = Some!int(123), y = None.init;
    assert(!x.isNone);
    assert(y.isNone);
    // Error: none of the overloads of template `isNone` are callable using argument types `!()(SumType!(None, Some!int))`
}

To work around this issue, you should define your option type as a struct using alias this, as described in this article on the D blog. (This will also give you nicer-looking error messages.) For Option, that would look like this:

struct Option(T)
{
    SumType!(None, Some!T) data;
    alias data this;
    this(Value)(Value value) { data = value; }
}

If I use this version of Option instead of the alias version, the example above compiles, and the unit test passes.

June 29, 2023

On Thursday, 29 June 2023 at 14:18:05 UTC, kiriakov wrote:

>

How to create option type over std.sumtype ?

enum None;
struct Some(T) { T x; }
alias Option = SumType!(Some!T, None);

I get
Error: undefined identifier T

Try

alias Option(T) = SumType!(Some!T, None);

Your version of Option isn't a template, so it doesn't know what T is. This version uses the eponymous template syntax for aliases.

June 29, 2023

On Thursday, 29 June 2023 at 15:19:45 UTC, Paul Backus wrote:

>

On Thursday, 29 June 2023 at 14:18:05 UTC, kiriakov wrote:

>
struct Option(T)
{
    SumType!(None, Some!T) data;
    alias data this;
    this(Value)(Value value) { data = value; }
}

https://dlang.org/blog/2018/05/21/complicated-types-prefer-alias-this-over-alias-for-easier-to-read-error-messages/

Thanks, it's worked.