-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
IArray #4791
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
IArray #4791
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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]