Conversation
|
copy pasted segments of discussion from discord, maybe someone else could make this work:
|
|
I think we could possibly solve some of these issues with a function like: def extractClassTag[A](arr: Array[A]): ClassTag[_] = {
val componentClass = arr.getClass.getComponentType
ClassTag(componentClass)
}and also using I think we need to get away from making the fake class tag from Any in every case. |
There was a problem hiding this comment.
Another thing we could do is break this up.
There are definitely sound typeclasses you can implement:
Hash[IArray[A]], Show[IArray[A]], Order[IArray[A]] Eq[IArray[A]] Foldable[IArray[A]]
I think all of those can be implemented without any casts or any funny business. We could add those first.
The ones that need to create IArray[A] parametrically may not be sound, and they may have to go into alleycats or something if we can't find a way to make them reliable.
|
|
||
| def empty[A]: IArray[A] = { | ||
| implicit val fakeClassTag: ClassTag[A] = summonFakeTag[A] | ||
| IArray.empty[A] |
There was a problem hiding this comment.
IArray is defined as covariant:
https://github.com/scala/scala3/blob/b8afeea3de732d0cfccaa372e38af1bc02f7eb31/library/src/scala/IArray.scala#L8
So, I think we can return empty[Nothing] here and it will type check without any casts.
| IArray.empty[A] | ||
| } | ||
|
|
||
| def combineK[A](x: IArray[A], y: IArray[A]): IArray[A] = { |
There was a problem hiding this comment.
So, something like:
val cx = getClassTag(x)
val cy = getClassTag(y)
if (cx.runtimeClass.isAssignableFrom(cy)) {
// cy <:< cx
implicit val ctA: ClassTag[A] = cx.asInstanceOf[ClassTag[A]
x.appendAll(y)
}
else if (/* check the opposite */ {
}
else {
// neither may be subclasses because one could be a primitive Int and the other a boxed Int, for example.
// just do boxing here
implicit val fakeClassTag: ClassTag[A] = ClassTag.Object.asInstanceOf[ClassTag[A]]
x.appendedAll(y)
}
Attempt to make IArray work
I personally think after some testing it will end up being impossible for IArray to work and that when possible, ArraySeq should be preferred.
Right now, all tests pass except stack safe traverse, but stack safe traverse fails because of a cast error, and that leads be to believe that the instance will end up being unsound in a lot of cases where it needs to cast between
Array[X <: AnyVal]andArray[X <: AnyRef]