This query got no love on Discord.

How do I use the sum of two singleton integer types? I am trying to make a ++ operator for concatenating a vector of length N with one of length M (both compile-time constants). The obvious thing

```
class Vec[N <: Int & Singleton](using n: ValueOf[N]) :
private val xs: Array[Double] = Array.ofDim[Double](n.value)
def ++[M <: Int & Singleton](other: Vec[M]) =
val result = Vec[N + M]
for i <- 0 until xs.length do
result.xs(i) = xs(i)
for i <- 0 until other.xs.length do
result.xs(i + xs.length) = other.xs(i)
result
```

(complete code on Scastie - An interactive playground for Scala.) fails with

```
No singleton value available for N + M where: M is a type in method ++ with bounds <: Int & Singleton.
```

There is a related bug report at https://github.com/lampepfl/dotty/issues/8257 that was closed, apparently without action. So how am I supposed to do this?

You can move the responsibility to prove that `N + M`

is a singleton value to the callsite of `++`

.

```
class Vec[N <: Int](using n: ValueOf[N]) :
private val xs: Array[Double] = Array.ofDim[Double](n.value)
def ++[M <: Int](other: Vec[M])(using ValueOf[N + M]) =
val result = Vec[N + M]
for i <- 0 until xs.length do
result.xs(i) = xs(i)
for i <- 0 until other.xs.length do
result.xs(i + xs.length) = other.xs(i)
result
```

That seems to work in this scastie:

1 Like

Thank you very much! That works.

I would love to understand why. My guess is the `using`

clause of the class.

I tried removing the `using`

clause, like this:

```
class Vec[N <: Int & Singleton] :
private val xs: Array[Double] = Array.ofDim[Double](summon[ValueOf[N]].value)
```

Now I got

```
No singleton value available for N.
```

With

```
class Vec[N <: Int & Singleton] :
private val xs: Array[Double] = Array.ofDim[Double](valueOf[N])
```

the message becomes even less helpful:

```
cannot reduce summonFrom with patterns : case given ev @ _:ValueOf[N]
```

Obviously, I ascribe too much power to the `Singleton`

bound, perhaps because of the wording in https://scala-lang.org/api/3.x/scala/Singleton.html: “When a type parameter has an explicit upper bound of Singleton, the compiler infers a singleton type.” Clearly here it did not.

Is that how it should be, or should I report a bug?

Thanks,

Cay

I think your analysis is pretty accurate. I’m not sure there’s a bug here though. But the error messages could definitely be better.

Thanks very much! I filed https://github.com/lampepfl/dotty/issues/15829, noting that either this is a bug or the error message needs work.

1 Like