TypeFunction example: filtering types

Stefan Koch uplink.coder at googlemail.com
Thu Oct 8 10:59:23 UTC 2020


Hi there,

Atlia just wrote of what he thinks first class type should allow 
him to do:
https://forum.dlang.org/post/uscehdzicfluyjyspocm@forum.dlang.org

Luckily he does not actually require first class types for this.
type functions do exactly what he wants.

he wrote:

----
import std.algorithm: filter, equal;

type[] types = [int, uint, long, ulong];
auto size4 = types.filter!(a => a.sizeof == 4);
assert(equal(size4, [int, uint]));
---

that of course won't compile because the assert has to be a 
static assert.
also the array literal of types is currently unsupported.
and for some reason isInputRange fails to instantiate for 
`alias[]`
which means we can't use phobos directly.

So we have to implement phobos filter and phobos equal ourselves.
Similarly `==` is not defined for types right now ... and I don't 
see how it makes sense,
given we have the is expression ... which means we have to pass a 
predicate to equals.
Other than that, his code runs with type functions right now!

---
alias type = alias;

type[] makeTypeArray(type[] types ...)
{
     return types;
}


// has to be written because right now, alias.init is the 
errorType;
// which means that is() and __traits(compiles) may fail if 
alias.init is used.

auto filter(alias pred, E)(E array) if (is(typeof(E.init[0]) == 
alias))
{
     E result;
     size_t len;
     result.length = array.length;
     foreach(e;array)
     {
         if (pred(e))
         {
             result[len++] = e;
         }
     }
     return result[0 .. len];
}

bool equal(alias pred, E)(E array1, E array2) if 
(is(typeof(E.init[0]) == alias))
{
     if (array1.length != array2.length)
         return false;

     immutable len = array1.length;

     foreach(i; 0 .. len)
     {
         if (!pred(array1[i], array2[i]))
         {
             return false;
         }
     }
     return true;
}

enum type[] types = makeTypeArray(int, uint, long, ulong);
pragma(msg, makeTypeArray(int, uint, long, ulong).tupleof);
enum type[] size4 = types.filter!((type a) => a.sizeof == 4);
static assert(equal!((type a, type b) => is(a == b)) (size4, 
makeTypeArray(int, uint)));
pragma(msg, size4); // unsurprisingly prints [(int), (uint)]

---

Cheers,
Stefan


More information about the Digitalmars-d mailing list