std.sumtyp and option ?

Paul Backus snarwin at gmail.com
Thu Jun 29 15:19:45 UTC 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][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/


More information about the Digitalmars-d-learn mailing list