question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

unexplained "ambiguous implicit arguments" error

See original GitHub issue

Compiler version

3.1.1

Minimized code

The setup definitions

object repro:
    abstract class Add[VL, VR]:
        type VO
        def apply(vl: VL, vr: VR): VO

    object Add:
        // invoking this rule(same-type args) seems to work as expected
        transparent inline given [V](using num: scala.math.Numeric[V]): Add[V, V] =
            new Add[V, V]:
                type VO = V
                def apply(vl: V, vr: V): V = num.plus(vl, vr)

        // trying to invoke this rule (differing types) causes strange error
        transparent inline given [VL, VR](using
            nev: scala.util.NotGiven[VL =:= VR],
            numL: scala.math.Numeric[VL],
            numR: scala.math.Numeric[VR]): Add[VL, VR] =
            new Add[VL, VR]:
                type VO = Double
                def apply(vl: VL, vr: VR): Double = numL.toDouble(vl) + numR.toDouble(vr)

    transparent inline def plus[VL, VR](vl: VL, vr: VR)(using add: Add[VL, VR]): add.VO =
        add(vl, vr)

Output

scala> import repro.*
                                                                                                                                                               
scala> plus(1,1)  // invoking with identical types works
val res0: Int = 2
                                                                                                                                                               
scala> plus(1f,1f)
val res1: Float = 2.0
                                                                                                                                                               
scala> plus(1d,1d)
val res2: Double = 2.0
                                                                                                                                                               
scala> plus(1,1d)  // attempting to trigger the different-types rule errors out unxpectedly
-- Error: ----------------------------------------------------------------------
1 |plus(1,1d)
  |          ^
  |ambiguous implicit arguments of type coulomb.repro.Add[Int, Double] found for parameter add of method plus in object repro.
  |I found:
  |
  |    coulomb.repro.Add.given_Add_V_V[V](
  |      /* ambiguous: both object DoubleIsFractional in object Numeric and object LongIsIntegral in object Numeric match type Numeric[V] */
  |        summon[Numeric[V]]
  |    )
  |
  |But both object DoubleIsFractional in object Numeric and object LongIsIntegral in object Numeric match type Numeric[V].
1 error found

Expectation

I would expect these rules to resolve correctly with no ambiguities

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
armanbilgecommented, Feb 28, 2022

@erikerlandson here’s a potential workaround.

object repro:
    abstract class Add[VL, VR]:
        type VO
        def apply(vl: VL, vr: VR): VO

    object Add:
        // invoking this rule(same-type args) seems to work as expected
        transparent inline given sameSame[VL, VR](using num: scala.math.Numeric[VL], same: VR =:= VL): Add[VL, VR] =
            new Add[VL, VR]:
                type VO = VL
                def apply(vl: VL, vr: VR): VL = num.plus(vl, same(vr))

        // trying to invoke this rule (differing types) causes strange error
        transparent inline given different[VL, VR](using
            nev: scala.util.NotGiven[VL =:= VR],
            numL: scala.math.Numeric[VL],
            numR: scala.math.Numeric[VR]): Add[VL, VR] =
            new Add[VL, VR]:
                type VO = Double
                def apply(vl: VL, vr: VR): Double = numL.toDouble(vl) + numR.toDouble(vr)

    transparent inline def plus[VL, VR](vl: VL, vr: VR)(using add: Add[VL, VR]): add.VO =
        add(vl, vr)
1reaction
benhutchisoncommented, Nov 5, 2022

@armanbilge I sure am grateful we have you in the Scala community. That’s a handy trick to know 🙏

For anyone else following along from home, this is the apply that Eric makes reference to above

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unexpected ambiguous implicit argument error - Compiler
I found a strange behavior of compiler. The minimal code snippet that I was able to create is trait Accessor: def get[T](using parser: ......
Read more >
Ambiguous implicit values - scala - Stack Overflow
I've been thinking I understand scala implicits until recently faced strange problem. In my application I have several ...
Read more >
Implicit arguments — Coq 8.16.1 documentation
An implicit argument of a function is an argument which can be inferred from contextual knowledge. There are different kinds of implicit arguments...
Read more >
implicit parameter precedence again - eed3si9n
1, locally declared implicits are preferred over imported ones. The problem is that the spec does not cover such behavior. My original ...
Read more >
ambiguous implicit arguments of type sttp.tapir.codec ...
As I've already tried to explain in the comments, the problem is that the method ... lampepfl/dottyunexplained "ambiguous implicit arguments" error#14585.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found