www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Result handing in D: some|none

reply 9il <ilyayaroshenko gmail.com> writes:
[mir.algebraic](http://mir-core.libmir.org/mir_algebraic.html) 
additions:
  - `some`, `none`, and `suit` second level algebraic visitor 
handlers
  - ` reflectErr` UDA
  - `Err` auto expanded wrapper when ` reflectErr` can't be used
  - Required utility API

```d
import mir.algebraic;
import mir.conv: to;

alias orElse(alias fun) = visit!(some!"a", none!fun);
alias convertErrToString = orElse!(to!string);

// can be any other type including integer enums
 reflectErr
static struct ErrorInfo {
     string msg;
     auto toString() const { return msg; }
}

alias V = Variant!(Err!string, ErrorInfo, long, double);
alias R = typeof(convertErrToString(V.init));

static assert(is(R == Variant!(string, long, double)), 
R.stringof);
assert(convertErrToString(V(1)) == 1);
assert(convertErrToString(V(1.0)) == 1.0);
assert(convertErrToString(ErrorInfo("b")) == "b");
assert(convertErrToString("Ш".err) == "Ш");
```
Jan 30
next sibling parent 9il <ilyayaroshenko gmail.com> writes:
On Sunday, 30 January 2022 at 10:58:33 UTC, 9il wrote:
 [mir.algebraic](http://mir-core.libmir.org/mir_algebraic.html)
I like `suit` a lot. It helps to define very clean visitors. ```d import std.traits: isDynamicArray, Unqual; import std.meta: templateNot; alias V = Variant!(long, int, string, long[], int[]); alias autoGetElementType = match!( (string s) => "string", // we override the suit handler below for string suit!(isDynamicArray, a => Unqual!(typeof(a[0])).stringof), suit!(templateNot!isDynamicArray, a => Unqual!(typeof(a)).stringof), ); assert(autoGetElementType(V(string.init)) == "string"); assert(autoGetElementType(V((long[]).init)) == "long"); assert(autoGetElementType(V((int[]).init)) == "int"); assert(autoGetElementType(V(long.init)) == "long"); assert(autoGetElementType(V(int.init)) == "int"); ```
Jan 30
prev sibling parent reply SealabJaster <sealabjaster gmail.com> writes:
On Sunday, 30 January 2022 at 10:58:33 UTC, 9il wrote:
 ...
Nice work! Anytime I see things like this it makes me wish D would adopt some form of pattern matching. expressive it can be in certain cases, i.e.: ```fsharp let (|Seconds|NotANumber|) (str : string) = let mutable value = 0.0 match Double.TryParse(str, &value) with | true -> Seconds value | false -> NotANumber ...somewhere in an expression/function match model.Duration with | Seconds s -> ValidRequest { ...omitted } | NotANumber -> InvalidRequest "Duration is not a valid number" ```
Jan 30
parent SealabJaster <sealabjaster gmail.com> writes:
On Sunday, 30 January 2022 at 16:08:17 UTC, SealabJaster wrote:
 On Sunday, 30 January 2022 at 10:58:33 UTC, 9il wrote:
 ...
...
I missed the full example I wanted to give: ```fsharp let (|Seconds|NotANumber|) (str : string) = let mutable value = 0.0 match Double.TryParse(str, &value) with | true -> Seconds value | false -> NotANumber let (|ValidRequest|InvalidRequest|) (model : PutSubModel, rs : ResultSet) = if model.Taken > DateTimeOffset.UtcNow then InvalidRequest "This result was taken in the future?" ... else match model.Duration with | Seconds s -> ValidRequest { ... } | NotANumber -> InvalidRequest "Duration is not a valid number" let rec handleModel (model: PutSubModel) (array: PutSubModel[]) = match (model, rs) with | InvalidRequest error -> Some error | ValidRequest req -> req |> db.Add |> ignore if array.Length = 0 then None else handleModel array.[0] array.[1..] ```
Jan 30