rbs
rbs copied to clipboard
Cannot specify type variables for `instance`
class MyWrapper[E]
def self.of: (E) -> instance # RBS::UnknownTypeName (it’s not inferred from `MyWrapper[E]`)
def self.of: (E) -> instance[E] # RBS::SyntaxError
def self.of: [E] (E) -> instance # ok, but `[E]` is not used in practice (it’s not the same `[E]` as the one in `MyWrapper[E]`)
def self.of: (untyped) -> instance # ok, but `untyped` is bad
end
Even Steep is aware of this limitation: https://github.com/soutaro/steep/blob/v1.5.3/lib/steep/subtyping/check.rb#L307
Proposal: instance[E]?
The problem might be significant for class as well:
https://github.com/soutaro/steep/blob/v1.5.3/lib/steep/subtyping/check.rb#L322
I know there are some cases that requires that kind of types, but we don't have a plan to support it at least for now.
A class inheriting from a generic class may be non-generic, and what can we do for instance[T] (and maybe self[T]) types?
class Generic[T]
def foo: () -> instance[Array[T]]
end
class NonGeneric < Generic[String]
end
# Even worse if it inherited by another generic class.
class AnotherGeneric[T] < NonGeneric
end
def self.of: (E) -> instance # RBS::UnknownTypeName (it’s not inferred from `MyWrapper[E]`)
How about letting class methods pick up generics?
def self.of: (E) -> instance # RBS::UnknownTypeName (it’s not inferred from `MyWrapper[E]`)How about letting class methods pick up generics?
Would this rather be a Steep job? Unless the RBS gem itself also involved…
How about letting class methods pick up generics?
Generics in RBS currently is for instance types.
I think no other programming language allows this. Do you know any example?
The type you want would be this?
def self.of: [E, T < MyWrapper[E]] (E) -> T
Steep allows explicit type application, and it will help:
MyWrapper.of(123) #$ Integer, AnotherWrapper # E=Integer, T=AnotherWrapper
The type you want would be this?
def self.of: [E, T < MyWrapper[E]] (E) -> T
Almost. The strength of instance is that it indicates the ::of of MyWrapperSubclass[E] < MyWrapper[E] returns a MyWrapperSubclass[E] and not an unspecific MyWrapper[E].
Steep allows explicit type application, and it will help:
MyWrapper.of(123) #$ Integer, AnotherWrapper # E=Integer, T=AnotherWrapper
Good to know more :+1:. Steep really lacks detailed and locatable docs for Ruby annotations, both in-line and #@type styles.