Lanbo
Lanbo

Reputation: 15712

Value of an object

Simple question, I have code like this:

class Context[A] {
    def t: A
}

object Context {
    implicit object StandardContext extends Context[SomeObject] {
        def t = SomeObject
    }
}

SomeObject is an object that holds values and functions that I would like to access in my Context. Unfortunately the different types for A I would like to include do not have a common parent class, other than java.lang.Object.

SomeObject is defined like this:

final object SomeObject {
    def func1 = ...
    def func2 = ...
}

In some code that's not mine. But the Scala compiler complains SomeObject is not a value when I try the thing above. As far as I know it, an object in scala is a singleton class, so it would be a type, yes, but also a value, the only value of its own type.

What I wanna do is stuff like this:

class Foo[A](bar: Int)(implicit context: Context[A]) {
    def baz = context.t.baz
}

Anyone can tell me how to solve this or have a better idea of solving it?

Upvotes: 2

Views: 494

Answers (3)

Synesso
Synesso

Reputation: 39018

Anyone ... have a better idea of solving it?

How about lifting the wanted function from the object and using that as your implicit?

scala> object SomeObject {
     |  def baz = "hi"
     | }
defined module SomeObject

scala> implicit val baz = SomeObject.baz _
baz: () => java.lang.String = <function0>

scala> class Foo(bar: Int)(implicit baz: () => String) {
     |   def bazme = baz()
     | }
defined class Foo

scala> new Foo(100).bazme
res2: String = hi

If the function is not of a consistent type, then the function type itself could be parameterised. E.G.

class Foo[A](bar: Int)(implicit baz: () => A) // or
class Foo[A](bar: Int)(implicit baz: A) // or
class Foo[A, B](bar: Int)(implicit baz: A => B) // etc

Using this approach the implicit can be lifted from an Object, or an instance. It doesn't matter.

Upvotes: 0

Kevin Wright
Kevin Wright

Reputation: 49705

Your non-code description already asserts that the type param A of Context will be AnyRef, and so renders it useless. Context is essentially:

class Context { def t: AnyRef }

You certainly can't call context.t.baz on some instance of this.

Given that there's no helpful parent class available, you might want to roll your own, via structural types. type classes may also be a good fit, but it's impossible to advise better without knowing the actual problem you're trying to solve.

Upvotes: 0

user unknown
user unknown

Reputation: 36269

implicit object StandardContext extends Context[SomeObject] {
    def t = SomeObject

The first SomeObject is a type, a type-parameter for Context, but in the second row it is used as if it were a variable.

Think of

 ... List [Int] {
     def x = Int // fail

Int is a type, not a variable, so x can't return Int, it could only return an integer.

Upvotes: 3

Related Questions