Thread overview
Recursively defined matcher function
Jan 03, 2021
Per Nordlöw
Jan 03, 2021
sighoya
Jan 03, 2021
sighoya
Jan 03, 2021
sighoya
Jan 03, 2021
Per Nordlöw
January 03, 2021
How can I define a function type `Matcher` that takes an array of `Matcher`s and returns an instance of a `struct Match` defined as

struct Match
{
@safe pure nothrow @nogc:
    static Match zero()
    {
        return typeof(return)(0);
    }
    static Match none()
    {
        return typeof(return)(_length.max);
    }
    /// Match length in number of UTF-8 chars or 0 if empty.
    @property uint length()
    {
        return _length;
    }
    bool opCast(U : bool)() const
    {
        return _length != _length.max;
    }
    this(size_t length)
    {
        assert(length <= _length.max);
        this._length = cast(typeof(_length))length;
    }
    const uint _length;                // length == uint.max is no match
}

I've tried

    alias Matcher = Match function(Matcher[] matchers...);

but it errors as

    recursive alias declaration
January 03, 2021
On Sunday, 3 January 2021 at 18:26:44 UTC, Per Nordlöw wrote:
> I've tried
>
>     alias Matcher = Match function(Matcher[] matchers...);
>
> but it errors as
>
>     recursive alias declaration

The closest thing can I think of is:
```
alias matcherSignature(T:matcherSignature!T) = T (T[] matchers...);
```

I think we would require proper singleton types to model this as:

```
matcherSignature(matcherSignature.type[] matcherSignatures ...)
```
January 03, 2021
On Sunday, 3 January 2021 at 18:49:40 UTC, sighoya wrote:
> ```
> alias matcherSignature(T:matcherSignature!T) = T (T[] matchers...);
> ```
>

Ahhh, I meant this:

```
alias matcherSignature(T:matcherSignature!T) = Matcher (T[]  matchers...);
``

> I think we would require proper singleton types to model this as:
>
> ```
> matcherSignature(matcherSignature.type[] matcherSignatures ...)
> ```

and this:

```
Matcher matcherSignature(matcherSignature.type[] matcherSignatures...)
```
January 03, 2021
On Sunday, 3 January 2021 at 18:55:58 UTC, sighoya wrote:
>```
>alias matcherSignature(T:matcherSignature!T) = Matcher (T[]  matchers...);
>```

Yet, it is right:

```
alias matcherSignature(T:matcherSignature!T) = Matcher function(T[]  matchers...);
```

But it didn't work likewise, you have to instantiate it infinitely in nesting order.

I think you either need some kind of nominalism to state matcherSignature!T exists for any T or you need to end it after a certain depth:

```
struct theEnd {}

template matcherSignature(T) if (T==matcherSignature!T || T==theEnd)
{
    Matcher function(T[] matchers...) fp;
}
```

January 03, 2021
On Sunday, 3 January 2021 at 18:26:44 UTC, Per Nordlöw wrote:

>     alias Matcher = Match function(Matcher[] matchers...);
>
> but it errors as
>
>     recursive alias declaration

Preferrably I wanted a non-templated definition.