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