2

I am trying to create a type class inside IntelliJ Scala Worksheet. So I started with trait like this

trait Show[A] {
  def show(a : A) : String
}

and created a companion object

object Show {

  def show[A](a: A)(implicit sh: Show[A]) = sh.show(a)

  implicit val intCanShow: Show[Int] =
    new Show[Int] {
      def show(int: Int): String = s"int $int"
    }

}

When I try

println(Show.show(20))

I get this error.

Error:(50, 26) could not find implicit value for parameter sh: Show[Int]
println(Show.show(20))

But when I take the intCanShow out of the object Show, it works fine. Why cannot scala acess the the implicit inside the object?

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
Srinivas
  • 2,010
  • 7
  • 26
  • 51
  • 5
    Are you running this in the REPL or in a worksheet? `object Show` is not the companion object for the trait unless they are compiled together as part of the same compilation object. You can use the REPL's `:paste` mode to accomplish this. – jwvh Sep 12 '19 at 19:32
  • Yes it is in a worksheet. Got it thanks. – Srinivas Sep 12 '19 at 21:24

2 Answers2

3

Implicit resolution tries companion objects so your code seems ok. However for an object to become a companion it must satisfy the following two requirements

  1. A companion object is an object with the same name as a class or trait, and
  2. is defined in the same source file as the associated class or trait.

The following warning means the second requirement is not satisfied:

defined object Show
warning: previously defined trait Show is not a companion to object Show.
Companions must be defined together; you may wish to use :paste mode for this.

To satisfy second requirement we have to use Plain evaluation model in Scala Worksheet, or :paste mode in Scala REPL.

Scala Worksheet Plain evaluation model

To define a companion object in IntelliJ Scala Worksheet change Run type to Plain like so

  1. Show Worksheet Settings
  2. Select tab Settings for *.sc
  3. Change Run type from REPL to Plain

Scala REPL paste mode

As per @jwvh suggestion, make sure to enter paste mode

If a class or object has a companion, both must be defined in the same file. To define companions in the REPL, either define them on the same line or enter :paste mode.

as demonstrated here.

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
1

Your example appears to work as expected when run as a scala script.
With the following in a file named test.sh and marked executable

#!/usr/bin/env scala
trait Show[A] {
  def show(a : A) : String
}
object Show {
  def show[A](a: A)(implicit sh: Show[A]) = sh.show(a)

  implicit val intCanShow: Show[Int] =
    new Show[Int] {
      def show(int: Int): String = s"int $int"
    }
}

println(Show.show(20))

I observe

bash-3.2$ ./test.sh
int 20
jq170727
  • 13,159
  • 3
  • 46
  • 56
  • yes thanks,I just figured that the worksheet cannot take companion objects. Hence the implicit could not be accessed from the trait. – Srinivas Sep 13 '19 at 09:49