What does `[> SomeType ]` mean for a type annotation?


Quick question on type annotations: What does [> SomeType ] mean for a type annotation? How is it different to just SomeType?

To make it concrete, I’ve got this type in my code and I’m trying to understand what it means:

  Apoll    Pervasives.result(
  [> Prometo.error],

Is that substantially different to:

  Apoll    Pervasives.result(


It’s a lower bound type constraint. The type in the brackets is a polymorphic variant, and it means “all types that have at least” the variants in Prometo.error.

Here’s a good write up that also explain this concept: https://2ality.com/2018/01/polymorphic-variants-reasonml.html#from-concrete-types-to-type-constraints.


In Prometo terms it means that all Prometo promises may have the error cases in the variant, or more. This becomes relevant when trying to handle the promise or recover from failures. The typechecker will work out specifically what other cases there might be and ask you to handle them. E.g.

|> Prometo.Error.recover(~f=fun
  | `Prometo_error(jsError) => ...
  | `Your_app_error => ...
  | _ => ...default...)


Thank you, that makes sense! It’s very useful that you can extend the set of error types, I didn’t know that!


No prob :slight_smile: yeah that’s the cool thing about the composable error handling design. While processing promises, all errors must unify to the same type, and when different functions can return different polymorphic variant tags, they will all get added up to progressively bigger unions of all the possible cases. And this union will be calculated at compile time. Very cool.


Type Annotations are a new feature added in PEP 484 that allow for adding type hints to variables. They are used to inform someone reading the code what the type of a variable should be. This brings a sense of statically typed control to the dynamically typed Python. This is accomplished by adding : after initializing/declaring a variable.

An example is shown below, which adds the : int when we declare the variable to show that age should be of type int.

A helpful feature of statically typed languages is that the value of a variable can always be known within a specific domain. For instance, we know string variables can only be strings, ints can only be ints, and so on. With dynamically typed languages, its basically anyone’s guess as to what the value of a variable is or should be.

We can use the expected variable’s type when writing and calling functions to ensure we are passing and using parameters correctly. If we pass a str when the function expects an int, then it most likely will not work in the way we expected.