How do I enrich a package object?
Asked Answered
J

1

10

I recently discovered that one can use the Pimp Enrich My Library pattern to add methods to companion objects using .type:

object Whatever { }

implicit class WhateverExtensions(val obj: Whatever.type) {
    def greet = println("Hi!")
}

Whatever.greet

Unfortunately the same doesn't seem to work for package objects like scala.math:

implicit class MathExtensions(val obj: scala.math.type) {
    def min(x: Money, y: Money): Money = ???
}

I get the following compiler error:

Error:(153, 47) type mismatch;
 found   : math.type
 required: AnyRef
Note that math extends Any, not AnyRef.
Such types can participate in value classes, but instances
cannot appear in singleton types or in reference comparisons.
    implicit class MathExtensions(val obj: scala.math.type) extends AnyVal {
                                                 ^

Is it possible to enrich a package object?

Jasmine answered 19/5, 2015 at 23:24 Comment(0)
H
9

I don't think it's possible in that fashion, though the documentation is extremely thin. The compiler is clearly treating it differently than a singleton. Even if that method compiled, import scala.math._ would certainly not import your min method, as there is nothing to trigger the implicit conversion. And well, if math.customMin was possible, that would require two imports.

It is possible in another way. We can define anything we want in the scala.math package. We can't define methods at the top-level, though, so we need to employ some object trickery to make it work.

package scala.math

object intMin extends ((Int, Int) => Int) {
    def apply(x: Int, y: Int): Int = x + y
}

Some test:

import scala.math._

object Test extends App {

    println(intMin(4, 10))

}
Halimeda answered 20/5, 2015 at 1:0 Comment(2)
Not much in the docs at all: scala-lang.org/files/archive/spec/2.11/…. It seems impossible to get the type of that thing: type T = 'math'.type gives "Error:(5, 12) stable identifier required, but scala.<math: error> found. type T = math.type".Dasher
See also: scala-lang.org/docu/files/packageobjects/packageobjects.htmlHalimeda

© 2022 - 2024 — McMap. All rights reserved.