Can this be done? Defining type as in this Scala sample code

jmh530 john.michael.hall at gmail.com
Mon Feb 26 16:26:40 UTC 2018


On Monday, 26 February 2018 at 15:43:54 UTC, Bienlein wrote:
> Hello,
>
> just curious whether this is a Scala speciality or whether it 
> could also be done in D. Here is some Scala code:
>
> 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)
>
> }
>
> In the code above list.sum compiles, because list only contains 
> values that are of type Numeric. The sum method looks like this:
>
> def sum[B >: A](implicit num: Numeric[B]): B = 
> foldLeft(num.zero)(num.plus)
>
> So sum compiles if all values can be converted to Numeric which 
> the compiler checks at compile time.
>
> For list2 this is not the case as "123" is a string and 
> therefore not of type Numeric. Calling functions on list2 ist 
> fine as long as no function is called that requires a 
> conversion to Numeric for each element in the list such as in 
> the case of sum.
>
> My question is now whether that kind of logic can also be 
> defined in D. My knowledge of D is too limited to find out in 
> reasonable time myself. Reason for my curiosity is that the 
> Scala solution relies on implicit conversion at compile time 
> which has its drawbacks (compilation times, colliding implicit 
> conversions the compiler cannot detect, etc.). So I just wanted 
> to see whether D does this in a clean way and I know that D 
> allows for some type parameter constraints to be set.
>
> Thansk for any answers,
> Bienlein

Probably more appropriate in the Learn forum.

I don't really know much Scala, but it seems like
>   val list2 = List(1, 2.4, 5, "123")
would fail to compile because List requires the values to be of a 
common type and "123" is a string. By contrast, a tuple could 
hold all those elements, but then it might fail when calculating 
the sum. Even in D, it's a little tricky to take the sum of a 
Tuple. You may as well just do a for loop.

So I suppose the question is can D do
>   val list = List(1, 2.4, 5)
>   val sum = list.sum
Phobos has list containers in std.container. However, usually you 
would use an array for something like this unless you have a 
reason to use a list. The 1 and 5 ints are implicitly casted to 
doubles in both versions.

//array version

import std.algorithm : sum;
import std.stdio : writeln;

void main()
{
     auto x = [1, 2.4, 5];
     writeln(x.sum);
}

//list version

import std.algorithm : sum;
import std.stdio : writeln;
import std.container : SList;

void main()
{
     auto x = SList!double(1, 2.4, 5);
     writeln(x[].sum);
}


More information about the Digitalmars-d mailing list