Tagged unions [Was: What's wrong with std.variant.Variant?]

Paul Backus snarwin at gmail.com
Tue Jun 16 16:26:14 UTC 2020


On Tuesday, 16 June 2020 at 12:44:54 UTC, Simen Kjærås wrote:
>
> I'm not Dukc, but here's an example I came up with:
>
[...]
>
> Essentially, there's shortcut returns for a few cases, but the 
> others have some common behavior, even better if this is 
> slightly different in one single place for one single held 
> type, so you can't really factor it out as a separate function.
>
> --
>   Simen

I think this is an instructive example, because it illustrates 
one of the key
differences between functional-style code and imperative-style 
code: explicit
coupling via funcion parameters and return values vs. implicit 
coupling via
shared state.

Here's how I would write it:

     float common1(float value)
     {
         // Lots of code that manipulates 'value'
     }

     float common2(float value)
     {
         // More code that manupulates 'value'
     }

     float special(string s, float value)
     {
         // Do something special for only one of the types,
         // but after doing lots of common things
     }

     float myFun(SumType!(float, int, string, int[]) a)
     {
         import std.functional: pipe;

         return a.match!(
             number => cast(float) number,
             (string s) =>
                 s.process
                     .common1
                     .pipe!(value => special(s, value))
                     .common2
             (int[] ia) =>
                 ia.process
                     .common1
                     .common2
         );
     }

You'll notice that I've taken the liberty of extracting each 
arbitrary "chunk"
of code indicated by a comment into its own function. In doing 
so, I've had to
make the inputs and outputs of those chunks explicit (and make 
some assumptions
about what they are). While this is a bit of extra work up front, 
I think it
makes the end result easier to understand--not to mention easier 
to unit test.

Exercise for the reader: how can this code be further refactored 
to eliminate
the duplication between the string and int[] cases?

(Solution: 
https://gist.github.com/pbackus/deda874eeddf587d938cb5d6213a0b84)


More information about the Digitalmars-d mailing list