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][1], 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][2]. (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.

[1]: https://issues.dlang.org/show_bug.cgi?id=1807
[2]: https://dlang.org/blog/2018/05/21/complicated-types-prefer-alias-this-over-alias-for-easier-to-read-error-messages/

Reply via email to