Can this be done? Defining type as in this Scala sample code
Bienlein
jeti789 at web.de
Wed Feb 28 08:45:00 UTC 2018
On Monday, 26 February 2018 at 19:36:33 UTC, Simen Kjærås wrote:
> On Monday, 26 February 2018 at 15:43:54 UTC, Bienlein wrote:
>> object Scratch extends App {
>>
>> // compiles:
>>
>> val list = List(1, 2.4, 5)
>> val sum = list.sum
>> println(sum)
>>
>>
>> // does not compile:
>>
>> val list2 = List(1, 2.4, 5, "123")
>> val sum2 = list2.sum
>> println(sum2)
>>
>> }
>
> There's nothing in the language or standard library that
> supports this. However, it's perfectly possible to make
> something with those semantics:
>
> import std.variant;
> import std.stdio;
>
> struct List(T) {
> T[] values;
>
> alias values this;
> }
>
> auto list(T...)(T args)
> {
> import std.traits : CommonType;
>
> static if (is(CommonType!T == void))
> List!Variant result;
> else
> List!(CommonType!T) result;
>
> result.length = T.length;
> foreach (i, e; args) {
> result[i] = e;
> }
> return result;
> }
>
> auto sum(T)(List!T lst)
> if (is(typeof(lst[0] + lst[0])) && !is(T == Variant))
> {
> T result = 0;
> foreach (e; lst) {
> result += e;
> }
> return result;
> }
>
> unittest {
> auto list1 = list(1, 2.4, 5);
> auto sum1 = list1.sum;
> writeln(sum1);
>
> auto list2 = list(1, 2.4, 5, "123");
> auto sum2 = list2.sum;
> writeln(sum2);
> }
>
>
> Since std.variant.Variant does operator overloads, we have to
> explicitly check if T == Variant in the sum function. For
> Variant, that's probably the correct choice. We could use
> Algebraic instead, but it also does operator overloads, even
> when no type in its arguments support them. Again, we could
> create our own - Algebraic and Variant are library types, after
> all.
>
> --
> Simen
Didn't have time so far to look into this. But thanks anyway.
More information about the Digitalmars-d
mailing list