Flow: Covariant member of tuple

Created on 2 Aug 2017  路  3Comments  路  Source: facebook/flow

Is there a way to annotate covariant member of tuple, similarly to covariant object properties?
(In context of ADTs tuple and record are analogous types i.e. a product type)

Extended example from docs:

class Person { name: string }
class Employee extends Person { department: string }

var employee: { who: Employee } = { who: new Employee };
var person: { +who: Person } = employee;

var employeeTuple: [Employee, number] = [new Employee, 1]
var personTuple: [Person, number] = employeeTuple // Error!

Try flow

Analogous way would be to mark first member as covariant like:

var employeeTuple: [+Employee, number] = [new Employee, 1]
var personTuple: [Person, number] = employeeTuple // This would type check since first member of employeeTuple is covariant

This syntax is not currently supported in Flow.

Readonly tuple would also be enough for our use case, but I am not sure there is such a thing.

property variance tuple feature request

Most helpful comment

Read-only tuples would be useful in iterators:

// `Iterator` is defined as `type Iterator<+T> = ...`
class SomeReadOnlyMap<K, +V> {
  values(): Iterator<V> { ... } // ok
  entries(): Iterator<[K, V]> // error, something like `$ReadOnlyTuple<K, V>` is required
}

So I see three solutions:

  1. Make all tuples read-only.
  2. Make $ReadOnlyTuple<A, B, C> or $ReadOnlyTuple<[A, B, C]> type, by analogy with $ReadOnlyArray.
  3. Allow variance declarations on tuple types (like type A = [+string, -number]).

The third has a problem with negative numbers. Currently type A = [-2] is valid, -2 is parsed as a number. One possible solution is allow only covariance (not contravariance) annotations.

All 3 comments

This looks like a great request. It's odd that tuples get neither the property variance of records nor at least the read-only option like arrays.

Support. Tuple read/write semantics seem kind of weird: they are mutable (t[0] = "hello" is okay), but only support read-only array properties (t.fill("wat") gives "property fill missing in $ReadOnlyArray", as described in the docs). Having covariance annotations or $ReadOnlyTuple<SomeNormalTuple> would be nice.

Read-only tuples would be useful in iterators:

// `Iterator` is defined as `type Iterator<+T> = ...`
class SomeReadOnlyMap<K, +V> {
  values(): Iterator<V> { ... } // ok
  entries(): Iterator<[K, V]> // error, something like `$ReadOnlyTuple<K, V>` is required
}

So I see three solutions:

  1. Make all tuples read-only.
  2. Make $ReadOnlyTuple<A, B, C> or $ReadOnlyTuple<[A, B, C]> type, by analogy with $ReadOnlyArray.
  3. Allow variance declarations on tuple types (like type A = [+string, -number]).

The third has a problem with negative numbers. Currently type A = [-2] is valid, -2 is parsed as a number. One possible solution is allow only covariance (not contravariance) annotations.

Was this page helpful?
0 / 5 - 0 ratings