Thread overview
Recursively defined matcher function
Jan 03
sighoya
Jan 03
sighoya
Jan 03
sighoya
January 03
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
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
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
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
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.