Preventing accidental argument type information loss


#1

Assume I have a library that exposes the following Foo and FooT:

trait Foo {type T}
trait FooT[T0] extends Foo {type T = T0}

The library user can use an argument of type Foo in several ways:

val ft = new FooT[Int]{}
def foo1[T](f : FooT[T]) = f
def foo2[F <: Foo](f : F) = f
def bad_foo(f : Foo) = f

Calling foo1(ft) or foo2(ft) will preserve the knowledge that T is Int, but calling bad_foo will not.
Is there some way I can warn the library user in cases similar to bad_foo?


#2

Why not just specify the return type?

def good_foo(f : Foo): Foo { type T = f.T } = f

#3

I don’t think the OP wants to return the Foo. That bad_foo, if I understood correctly, will be defined by the library user. Issue is, how do we enforce the user to retain the T in Foo[T].

Wondering if implicits are of potential use here.


#4

Exactly. Loosing T is a mistake on behalf of the user.


#5

If it’s important to preserve, use a type parameter instead of a type member. Type member syntax makes it easy to leave off and hard to preserve. Type parameter syntax makes it easier to preserve, and harder to leave off.


#6

Yes, of course. But I need to expose both to the user, to have the possibility to use Foo just in an upper-bound position.