On Thu, Jun 19, 2014 at 01:51:17PM -0700, H. S. Teoh via Digitalmars-d wrote:
> On Thu, Jun 19, 2014 at 04:29:12PM -0400, Etienne via Digitalmars-d wrote:
[...]
> > meh, this works:
> > 
> > 
> > writeln(currAssignment.safeDeref.typeInfo.ident.or("meh"));
> > 
> > ..
> >     static struct SafeDeref {
> >             T t;
> >             
> >             // Make the wrapper as transparent as possible.
> >             alias t this;
> > 
> >             // this overrides if null
> >             T or(T defVal){
> >                     if (t is t.init)
> 
> This assumes that t.init is not a possible valid field value. But in
> that case, there's no need to remap it, you just check for t.init
> instead. For pointers, where .init is null, this isn't a problem, but
> for things like int, where 0 is possible valid value, you may be
> accidentally mapping 0 to the default value when the given field
> actually exists (and has value 0)!
[...]

Actually, on second thoughts, maybe it *is* possible after all. The key
is to differentiate between null-able types, and non-nullable types. For
the latter, we expand the SafeDeref struct to store a boolean flag to
indicate whether or not the value exists, then .or() can check that flag
to see if it should return the default value. Basically, something like
this:

        struct SafeDeref {
                T t;

                static if (!is(t = null))
                        bool exists = true;

                ...
                T or(T defVal) {
                        return (exists) ? t : defVal;
                }
                ...
                auto opDispatch(...) {
                        ...
                        if (t is null)
                                return safeDeref(Memb.init, false)
                        else
                                return safeDeref(__traits(getMember...), true);
                }
        }

I'll try this out to see if it works!

This also has the advantage of becoming even closer to a real monad: by
checking for .exists, we can also overload operators to return a wrapper
with exists=false whenever one of the operands also has exists=false.


T

-- 
Why can't you just be a nonconformist like everyone else? -- YHL

Reply via email to