Strange scala 3 syntax - new without type

56 Views Asked by At
def flatMap[B](f: A => IO[B]): IO[B] = new:
  def unsafeRun = f(self.unsafeRun).unsafeRun

This method creates a new IO object

I don't understand the use of new without a type. Feels like structural type, but not quite sure. I'm Just starting to transition to scala 3.

1

There are 1 best solutions below

1
Mateusz Kubuszok On BEST ANSWER

What you described is a new feature of Scala 3, which allows you to drop type name when creating an anonymous instance of some class if the type can be inferred:

trait Foo {
  def a(i: Int): String
}

// this is what Scala 2 requires
val foo1: Foo = new Foo {
  def a(i: Int): String = i.toString
}

// this is what Scala 3 allows
val foo2: Foo = new { // Foo in inferred from value foo2 type
  def a(i: Int): String = i.toString
}

// this is Scala 3 with braceless syntax
val foo3: Foo = new:
  def a(i: Int): String = i.toString

While it feels like a structural typing it's a nominal typing with type inference extended to anonymous classes created with new keyword.

You could even use this in some nested contexts like:

trait Foo:
  def a(i: Int): String
trait Bar:
  def foo: Foo
trait Baz:
  def bar: Bar

val baz: Baz = new:
  def bar = new:
    def foo = new:
      def a(i: Int): String = i.toString

but it becomes unreadable almost immediately, which is why this presentation classifies it as an Scala-3-specific antipattern.

It might be a really nice way to quickly to hack some one-time-use script, but please avoid using it in larger long-living codebases.