Scala - Make implicit value classes available in another scope

I have a package foothat contains a class FStream. A package object foodefines several implicit value classes that extension methods provide for FStream. I would like to move these value classes from the package object and to my own separate files, but I also want them to always be available when I use FStream(or preferably when I use something from the package foo. Is it possible for this? I I tried to put implicit value classes in other objects, but I cannot extend to objects. I tried to put them in classes or traits, but implicit value classes can be defined only in other objects.

Foo / fstream.scala

package foo

class FStream {
  def makeFoo(): Unit = ???
}

Foo / package.scala

package foo

package object foo {

  // I want to move these definitions into separate files:

  implicit class SuperFoo(val stream: FStream) extends AnyVal {
    def makeSuperFoo(): Unit = ???
  }

  implicit class HyperFoo(val stream: FStream) extends AnyVal {
    def makeHyperFoo(): Unit = ???
  }
} 

/usage.scala

package bar

import foo._ // something nice and short that doesn't reference individual value classes

val x: FStream = ???
x.makeSuperFoo() // should work
x.makeHyperFoo() // should work
+4
1

.

FStream companion. FStream . .

Foo/FStream.scala

package foo

class FStream {
  def makeFoo(): Unit = ???
}

// companion provides implicit
object FStream extends FStreamOp

foo/FStreamOp.scala

package foo

// value class may not be a member of another class
class SuperFoo(val stream: FStream) extends AnyVal {
  def makeSuperFoo(): Unit = ???
}

class HyperFoo(val stream: FStream) extends AnyVal {
  def makeHyperFoo(): Unit = ???
}
trait FStreamOp {
  // you need to provide separate implicit conversion
  implicit def makeSuper(stream: FStream) = new SuperFoo(stream)
  implicit def makeHyper(stream: FStream) = new HyperFoo(stream)
}

usage.scala

import foo.FStream

object Main {
  def main(args: Array[String]): Unit = {
    val x: FStream = ???
    x.makeSuperFoo() // should work
    x.makeHyperFoo() // should work
  }
}
+3

Source: https://habr.com/ru/post/1669224/


All Articles