1

Working on Kotlin 1.3.61

Having this code:

abstract class ResourceObserver<T> : Observer<T> where T : Resource<T> {
    override fun onChanged(t: T) {
        when (t.status) {
            Status.LOADING -> { ... }
            Status.ERROR -> { ... }
            Status.SUCCESS -> { onSuccess(t.data) }
        }
    }

    abstract fun onSuccess(data: T?)
}

and trying to implement it

private val foo = object : ResourceObserver<Resource<Bar>> {
    override fun onSuccess(data: Bar?) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}

Compiler (Android Studio in this case) gives me this error:

Type argument is not within its bounds.
Expected: Resource<Resource<Bar>>
Found: Resource<Bar>

What is wrong with my obviously erroneous code?

1
  • Keep giving me the error, this time is: Type argument is not within its bounds. Expected: Resource<Bar> Found: Bar Commented Nov 28, 2019 at 11:45

2 Answers 2

2

The constraint where T : Resource<T> indeed requires that whatever type argument you use for T must also be Resource<T> (with T substituted by the type itself).

According to this constraint, the type argument that you provide for the implementation T := Resource<Bar> is checked for being Resource<T> ≡ Resource<Resource<Bar>> and fails this check.

For this constraint and the subtype to work, Bar would need to be a subtype (implementation) of Resource<Bar>.

Do you really need T to be a Reosurce<T> with the same T? Will it solve your problem if you use an upper bound with a star-projection T : Resource<*> or add another type parameter, as shown below?

abstract class ResourceObserver<T, R> : Observer<T> where T : Resource<R> { ... }

private val foo = object : ResourceObserver<Resource<Bar>, Bar> { ... }
Sign up to request clarification or add additional context in comments.

Comments

1

This looks like an attempt to use F-bounded polymorphism. For it to work you need to

  1. make Bar extend Resource<Bar>;

  2. make private val foo = object : ResourceObserver<Bar> { ... } instead of <Resource<Bar>>.

Usually Resource itself will be declared with the similar constraint

class Resource<T : Resource<T>>

so if you forget to do 1 Bar won't compile.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.