开发者

Value of an object

开发者 https://www.devze.com 2023-02-17 19:50 出处:网络
Simple question, I have code like this: class Context[A] { def t: A } object Context { implicit object StandardContext extends Context[SomeObject] {

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?


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消