Any idea why this fails to find the implicit view?
// Making B invariant fixes it.
sealed trait ImplicitlyStable[A, +B]
object ImplicitlyStable {
implicit def convertibleToStable[A, B](implicit
aToB: A => B,
// Removing bToB fixes it.
bToB: ImplicitlyStable[B, B]
): ImplicitlyStable[A, B] = ???
}
object Test {
def testConvertibleToStable[A, B](implicit
aToB: A => B,
bToB: ImplicitlyStable[B, B]
): ImplicitlyStable[A, B] =
implicitly[ImplicitlyStable[A, B]]
}
It fails with:
[error] !I e: ImplicitlyStable[A, B]
[error] ImplicitlyStable.convertibleToStable invalid because
[error] !I aToB: A => B
[error] No implicit view available from A => B.
[error]
[error] implicitly[ImplicitlyStable[A, B]]
[error] ^
[error] one error found
It says No implicit view available from A => B which is clearly not true as there is an implicit parameter of that type.
Is this one of those situations where it is inferring Nothing for B? If so, why would it do that?
If I add:
private def unexpected: Nothing = sys.error("Unexpected invocation")
implicit def nothingStableAmbig1[A]: ImplicitlyStable[Nothing, A] = unexpected
implicit def nothingStableAmbig2[A]: ImplicitlyStable[Nothing, A] = unexpected
implicit def nothingStableAmbig3[A]: ImplicitlyStable[A, Nothing] = unexpected
implicit def nothingStableAmbig4[A]: ImplicitlyStable[A, Nothing] = unexpected
Then it fails with:
[error] ambiguous implicit values:
[error] both method nothingStableAmbig3 in object ImplicitlyStable of type [A]ImplicitlyStable[A,Nothing]
[error] and method nothingStableAmbig4 in object ImplicitlyStable of type [A]ImplicitlyStable[A,Nothing]
[error] match expected type ImplicitlyStable[A,B]
[error] implicitly[ImplicitlyStable[A, B]]
[error] ^
So sure enough, it is inferring Nothing, but why?
It seems like this might be a bug in Scala 2 that has been fixed in Scala 3.
I raised an issue for it.
I'm not sure if there is any more reasoning behind why it is inferring Nothing. If anyone knows then that would be great.
Related
I'm trying to achieve something with ScalaTest and based on C. Hosrtmann's "Scala for the impatient" I think this is related to "Family polymorphism". Apparently I don't understand something about Scala's type system, so I fail.
To cut the long story short, this is what I'm trying to do.
I have a base (production) trait:
trait MaxPQ[Key] {
implicit protected val cmp: Ordering[_ >: Key]
...
def insert(v: Key): Unit
def max(): Key
def delMax(): Key
...
}
then there is a number of implementations (that use either a backing tree or an array).
In tests I want to create an abstract structure which would allow to test any implementation for three Ordered Keys: Char, Int, Double.
First I've written two behaviors (for empty and non-empty priority queues). Here's a snippet:
trait MaxPQBehaviours {
// underlying tests spec
self: BaseSpec =>
def nonEmptyMaxPQ[T <: Ordered[T], ImplLà <: MaxPQ[T]](instanceSupplier: () => ImplLà, sortedInput: List[T]): Unit = {
...
behavior of "size"
it should s"be equal to ${sortedInput.size}" in {
val instance = instanceSupplier()
instance.size() shouldEqual sortedInput.size
}
behavior of "max"
it should s"return the expected $max" in {
val instance = instanceSupplier()
instance.max() shouldEqual max
}
...
Finally to add a last layer of abstraction I'm adding a BaseMaxPQSpec that mixes-in the above MaxPQBehaviours and calls its behaviors for three abstract MaxPQ types. Here I'only provide example for Char:
trait BaseMaxPQSpec extends BaseSpec with MaxPQBehaviours {
type CharMaXPQ <: MaxPQ[Char]
def charMaxPQ: CharMaXPQ
val sortedCharsList: List[Char] = List[Char]('C', 'b', 'd', 'a', 'z').sorted
it should behave like nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
}
And this is where compiler spits this at me:
[error] ~/Algorithms/Chapter 2 Sorting/algorithms2_1/src/test/scala/ca/vgorcinschi/algorithms2_4/BaseMaxPQSpec.scala:18:25: inferred type arguments [Char,BaseMaxPQSpec.this.CharMaXPQ] do not conform to method nonEmptyMaxPQ's type parameter bounds [T <: Ordered[T],ImplLà <: ca.vgorcinschi.algorithms2_4.MaxPQ[T]]
[error] it should behave like nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
[error] ^
[error] ~/Algorithms/Chapter 2 Sorting/algorithms2_1/src/test/scala/ca/vgorcinschi/algorithms2_4/BaseMaxPQSpec.scala:18:42: type mismatch;
[error] found : () => BaseMaxPQSpec.this.CharMaXPQ
[error] required: () => ImplLà
[error] it should behave like nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
[error] ^
[error] ~/Algorithms/Chapter 2 Sorting/algorithms2_1/src/test/scala/ca/vgorcinschi/algorithms2_4/BaseMaxPQSpec.scala:18:56: type mismatch;
[error] found : List[Char]
[error] required: List[T]
[error] it should behave like nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
[error] ^
[error] three errors found
[error] (Test / compileIncremental) Compilation failed
[error] Total time: 12 s, completed Feb 15, 2020 6:21:35 PM
What is the correct way to set-up my testing framework? Please don't hesitate to ask for details, clarifications.
Given
nonEmptyMaxPQ(() => charMaxPQ, sortedCharsList)
type inference deduces type T = Char because the type of charMaxPQ is MaxPQ[Char], thus
T <: Ordered[T]
becomes Char <: Ordered[Char]
which certainly is not true. Perhaps try specifying Ordering like so
def nonEmptyMaxPQ[T: Ordering, Impl <: MaxPQ[T]](instanceSupplier: () => Impl, sortedInput: List[T])
Note the difference between upper bound T <: Ordered[T] and context bound T: Ordering.
Using scala 2.12.4 I cannot get this code to work since it says
[error] .../src/main/scala/effect.scala:32:11: No ClassTag available for A
[error] Effect(effectDefinition)
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
here is the (simplified) code. the reason i need the class tag is to do a filtering later in the code (installEffect).
import scala.reflect.ClassTag
package object effect {
type EffectDefinition[A <: EffectBearing[A]] = A => Unit
case class Effect[A <: EffectBearing[A]](fx: A => Unit)(implicit tag: ClassTag[A]) {
def effectedType: Class[A] = tag.runtimeClass.asInstanceOf
}
trait EffectBearing[This <: EffectBearing[This]] {
def installEffect(effect: Effect[This]): Unit = {
effect.fx(this.asInstanceOf[This])
}
}
trait EffectPropagating {
def installEffect[T<: EffectBearing[T]](effect: Effect[T], typ: Class[T]): Unit =
find(typ).foreach(_.installEffect(effect))
protected def find[T <: EffectBearing[T]](typ: Class[T]): Set[T]
}
class Foo extends EffectBearing[Foo] {}
val fxFoo: EffectDefinition[Foo] = print(_)
def translate[A <: EffectBearing[A]](effectDefinition: EffectDefinition[A]): Effect[A] =
Effect(effectDefinition)
val fx = translate(fxFoo)
}
ps: is the usage of
tag.runtimeClass.asInstanceOf
very bad? I couldn't get around that cast
You have the following method:
def translate[A <: EffectBearing[A]](effectDefinition: EffectDefinition[A]): Effect[A] =
Effect(effectDefinition)
The Effect constructor requires an implicit ClassTag[A] but here A is a type parameter so the compiler doesn't know which concrete class it will be. And there is no ClassTag context bound on A in translate, so the compiler will not be able to find an implicit ClassTag[A].
I'm having compilation issues with generics. The code compiles fine when I use asInstanceOf. I want to get rid of asInstanceOf.
I saw some other questions related to the usage of asInstanceOf, but I didn't help me.
trait RoundRobin[R <: Resource, F[_] <: mutable.ListBuffer[_]] {
self: RoundRobin[R, F] =>
// some public functions
private def overrideMutableResourceList(original: F[R], updated: F[R]): F[R] = {
val tempPool = original.asInstanceOf[mutable.ListBuffer[R]]
original.indices.foreach(i => {
val e = updated(i).asInstanceOf[R]
tempPool.update(i, e)
})
tempPool.asInstanceOf[F[R]]
}
When I remove the asInstanceOf from tempPool.asInstanceOf[F[R]] I get the below error
[error] /Users/...../RoundRobin.scala:108: type mismatch;
[error] found : tempPool.type (with underlying type scala.collection.mutable.ListBuffer[R])
[error] required: F[R]
[error] tempPool
[error] ^
[error] one error found
[error] (clustering/compile:compileIncremental) Compilation failed
[error] Total time: 3 s, completed Oct 3, 2017 2:53:34 AM
This issue happens also for the line original.asInstanceOf[mutable.ListBuffer[R]]
What is the reason for this issue?
How can I avoid using asInstanceOf ?
Thanks
There's no relationship between F[A] and ListBuffer[A], only that ∀A∃B F[A] <: ListBuffer[B]. This is important:
type ConstLBInt[A] = ListBuffer[Int]
val x: RoundRobin[Resource, ConstLBInt] = ??? // Legal
// Tries to manipulate ListBuffer[Int]s as if they were ListBuffer[Resources]s
Change the declaration of your type to
trait RoundRobin[R <: Resource, F[A] <: mutable.ListBuffer[A]]
// ! !
This forces ∀A F[A] <: ListBuffer[A], so that e.g. the updated: F[R] in overrideMutableResourceList is known to be a ListBuffer[R].
There are probably other parts of the class that will be simplified by this.
I am trying to create a hlist implicitly.
case class A(value: Int)
implicit def lift(single: A): A :: HNil = single :: HNil
def something[L <: HList](l: L)(implicit lUBConstraint: LUBConstraint[L, A],
isHCons: IsHCons[L]) = {
println("works")
}
something(A(1) :: A(2) :: HNil) //works
something(A(1)) //not works
something(lift(A(1))) //works
something(A(1)) is not working. However, I use intellij idea and It can detect that lift is proper to use here.
Here is the error message from compiler.
inferred type arguments [Boot.A] do not conform to method something's type parameter bounds [L <: shapeless.HList]
[error] something(A(1)) //not works [error] ^ [error]
type mismatch; [error] found : Boot.A [error] required: L [error] something(A(1))
could not find implicit value for parameter lUBConstraint: shapeless.LUBConstraint[L, Boot.A] [error] something(A(1)
IIRC Scala implicit conversions don't trigger to satisfy type bounds.
You can modify your definition of something to allow any such conversions to work:
def something[X, L <: HList](x: X)(
implicit asHList: X => L,
lUBConstraint: LUBConstraint[L, A],
isHCons: IsHCons[L]
) = {
println("works")
}
For single argument, this will use your lift function, and <:< from Predef for actual HLists
How do I get around with equivalence of two path-dependent types that I know are the same but the compiler does not?
Using Scala 2.10.0 M7 I am trying to convert an AST from one universe to another.
case class MacroBridge(context: Context) {
def toMacroTree(tree: treehugger.forest.Tree): context.universe.Tree = ???
def fromMacroTree(tree: context.universe.Tree): treehugger.forest.Tree = ???
}
Within a macro implementation, I can use it as:
val bridge = treehugger.MacroBridge(c)
def fromMacroTree(tree: c.universe.Tree): Tree = bridge.fromMacroTree(tree)
However, this results to a compiler error:
[error] /scalamacros-getting-started/library/Macros.scala:21: type mismatch;
[error] found : c.universe.Tree
[error] required: bridge.context.universe.Tree
[error] possible cause: missing arguments for method or constructor
[error] def fromMacroTree(tree: c.universe.Tree): Tree = bridge.fromMacroTree(tree)
In the above code c is clearly the same value as bridge.context, but maybe because it's a value type checker cannot check it. Putting generalized type constraint did not help:
def fromMacroTree[A](tree: A)(implicit ev: A =:= context.universe.Tree): Tree =
In the macro this still resulted to an error:
[error] /scalamacros-getting-started/library/Macros.scala:21: Cannot prove that c.universe.Tree =:= bridge.context.universe.Tree.
[error] def fromMacroTree(tree: c.universe.Tree): Tree = bridge.fromMacroTree(tree)
I need the access to context.universe so I can get to other dependent types like TermName. Is there a better work around besides casting?:
def fromMacroTree(tree: c.universe.Tree): Tree =
bridge.fromMacroTree(tree.asInstanceOf[bridge.context.universe.Tree])
I could the following make to work:
case class MacroBridge[C <: Context](context: C) {
def fromMacroTree(tree: context.universe.Tree): context.universe.Tree = ???
}
trait MB {
def meth(c: Context) {
val bridge = MacroBridge[c.type](c)
def fromMacroTree(tree: c.universe.Tree): c.universe.Tree =
bridge.fromMacroTree(tree)
}
}
I had nearly the same problem some time ago.