Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8007897
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T17:58:25+00:00 2026-06-04T17:58:25+00:00

I am using scala 2.10.0-snapshot dated (20120522) and have the following Scala files: this

  • 0

I am using scala 2.10.0-snapshot dated (20120522) and have the following Scala files:

this one defines the typeclass and a basic typeclass instance:

package com.netgents.typeclass.hole

case class Rabbit

trait Hole[A] {
  def findHole(x: A): String
}

object Hole {
  def apply[A: Hole] = implicitly[Hole[A]]
  implicit val rabbitHoleInHole = new Hole[Rabbit] {
    def findHole(x: Rabbit) = "Rabbit found the hole in Hole companion object"
  }
}

this is the package object:

package com.netgents.typeclass

package object hole {

  def findHole[A: Hole](x: A) = Hole[A].findHole(x)

  implicit val rabbitHoleInHolePackage = new Hole[Rabbit] {
    def findHole(x: Rabbit) = "Rabbit found the hole in Hole package object"
  }
}

and here is the test:

package com.netgents.typeclass.hole

object Test extends App {

  implicit val rabbitHoleInOuterTest = new Hole[Rabbit] {
    def findHole(x: Rabbit) = "Rabbit found the hole in outer Test object"
  }

  {
    implicit val rabbitHoleInInnerTest = new Hole[Rabbit] {
      def findHole(x: Rabbit) = "Rabbit found the hole in inner Test object"
    }

    println(findHole(Rabbit()))
  }
}

As you can see, Hole is a simple typeclass that defines a method which a Rabbit is trying to find. I am trying to figure out the implicit resolution rules on it.

  • with all four typeclass instances uncommented, scalac complains about ambiguities on rabbitHoleInHolePackage and rabbitHoleInHole. (Why?)

  • if I comment out rabbitHoleInHole, scalac compiles and I get back “Rabbit found the hole in Hole package object”. (Shouldn’t implicits in the local scope take precedence?)

  • if I then comment out rabbitHoleInHolePackage, scalac complains about ambiguities on rabbitHoleInOuterTest and rabbitHoleInInnerTest. (Why? In the article by eed3si9n, url listed below, he found implicits btw inner and outer scope can take different precedence.)

  • if I then comment out rabbitHoleInInnerTest, scalac compiles and I get back “Rabbit found the hole in outer Test object”.

As you can see, the above behaviors do not follow the rules I’ve read on implicit resolution at all. I’ve only described a fraction of combinations you can do on commenting/uncommenting out instances and most of them are very strange indeed – and I haven’t gotten into imports and subclasses yet.

I’ve read and watched presentation by suereth, stackoverflow answer by sobral, and a very elaborate revisit by eed3si9n, but I am still completely baffled.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T17:58:26+00:00Added an answer on June 4, 2026 at 5:58 pm

    Let’s start with the implicits in the package object and the type class companion disabled:

    package rabbit {
      trait TC
    
      object Test  extends App {
        implicit object testInstance1 extends TC { override def toString = "test1" }
    
        {
          implicit object testInstance2 extends TC { override def toString = "test2" }
    
          println(implicitly[TC])
        }
      }
    }
    

    Scalac looks for any in scope implicits, finds testInstance1 and testInstance2. The fact that one is in a tighter scope is only relevant if they have the same name — the normal rules of shadowing apply. We’ve chosen distinct names, and there neither implicit is more specific than the other, so an ambiguity is correctly reported.

    Let’s try another example, this time we’ll play off an implicit in the local scope against one in the package object.

    package rabbit {
      object `package` {
        implicit object packageInstance extends TC { override def toString = "package" }
      }
    
      trait TC
    
      object Test  extends App {
        {
          implicit object testInstance2 extends TC { override def toString = "test2" }
    
          println(implicitly[TC])
        }
      }
    }
    

    What happens here? The first phase of the implicit search, as before, considers all implicits in scope at the call site. In this case, we have testInstance2 and packageInstance. These are ambiguous, but before reporting that error, the second phase kicks in, and searches the implicit scope of TC.

    But what is in the implicit scope here? TC doesn’t even have a companion object? We need to review the precise definition here, in 7.2 of the Scala Reference.

    The implicit scope of a type T consists of all companion modules
    (§5.4) of classes that are associated with the implicit parameter’s
    type. Here, we say a class C is associated with a type T, if it
    is a base class (§5.1.2) of some part of T.

    The parts of a type T are:

    • if T is a compound type T1 with ... with Tn,
      the union of the parts of T1, ..., Tn, as well as T itself,
    • if T is a parameterized type S[T1, ..., Tn], the union of the parts of S and
      T1,...,Tn,
    • if T is a singleton type p.type, the parts of the type of p,
    • if T is a type projection S#U, the parts of S as well as T itself,
    • in all other cases, just T itself.

    We’re searching for rabbit.TC. From a type system perspective, this is a shorthand for: rabbit.type#TC, where rabbit.type is a type representing the package, as though it were a regular object. Invoking rule 4, gives us the parts TC and p.type.

    So, what does that all mean? Simply, implicit members in the package object are part of the implicit scope, too!

    In the example above, this gives us an unambiguous choice in the second phase of the implicit search.

    The other examples can be explained in the same way.

    In summary:

    • Implicit search proceeds in two phases. The usual rules of importing and shadowing determine a list of candidates.
    • implicit members in an enclosing package object may also be in scope, assuming you are using nested packages.
    • If there are more than one candidate, the rules of static overloading are used to see if there is a winner. An addiotnal a tiebreaker, the compiler prefers one implicit over another defined in a superclass of the first.
    • If the first phase fails, the implicit scope is consulted in the much same way. (A difference is that implicit members from different companions may have the same name without shadowing each other.)
    • Implicits in package objects from enclosing packages are also part of this implicit scope.

    UPDATE

    In Scala 2.9.2, the behaviour is different and wrong.

    package rabbit {
      trait TC
    
      object Test extends App {
        implicit object testInstance1 extends TC { override def toString = "test1" }
    
        {
          implicit object testInstance2 extends TC { override def toString = "test2" }
    
          // wrongly considered non-ambiguous in 2.9.2. The sub-class rule
          // incorrectly considers:
          //
          // isProperSubClassOrObject(value <local Test>, object Test)
          //   isProperSubClassOrObject(value <local Test>, {object Test}.linkedClassOfClass)
          //   isProperSubClassOrObject(value <local Test>, <none>)
          //     (value <local Test>) isSubClass <none>
          //        <notype> baseTypeIndex <none> >= 0
          //        0 >= 0
          //        true
          //     true
          //   true
          // true
          //
          // 2.10.x correctly reports the ambiguity, since the fix for
          //
          // https://issues.scala-lang.org/browse/SI-5354?focusedCommentId=57914#comment-57914
          // https://github.com/scala/scala/commit/6975b4888d
          //
          println(implicitly[TC])
        }
      }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

The following compiles just fine using scala Beta1 and scalaz snapshot 5.0: val p1:
How to solve this using scala Actors: I have a program that finds out
I am using Scala combinatorial parser by extending scala.util.parsing.combinator.syntactical.StandardTokenParser . This class provides following
I'm just getting started with the Play Framework 2.0 (using current trunk 2.1-SNAPSHOT, Scala)
Using Scala 2.7.7: If I have a list of Options, I can flatten them
I have recently begun using Scala. I've written a DSL in it which can
I have my environment setup nicely using Scala, StringTemplate within the Google AppEngine. I
I'm using Scala 2.8 and defining an Enumeration like this: object Stooges extends Enumeration
I'm going to work on comparing around 300 binary files using Scala, bytes-by-bytes, 4MB
Before I had something like this (simplified), using sbt 0.11.3: // project/Build.scala import sbt._

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.