I'm curious about why I'm receiving this error because I thought the polymorphic type `a could be treated as basically any type.
Yep, you're right, 'a
means anything. But what it really means to be anything? The type of a value defines in which contexts this value could be used. For example, if your value has type int
then it could be used in any place where int
or ''a
are expected. Saying that your function is having type 'a
means that your function could be used instead of an int
a unit
or instead of any other function. Really, the type 'a` means that this value could be used instead of any other value.
Saying it differently the type of a function in your signature is your contract. And you're trying to over obligate yourself by saying that your function can fit anywhere. And the type checker is saying that you're not right - your function is only fittable in a very particular context
ApolloMutation.apolloMutationType(Config.t) => mutationFunctionType
It is not even polymorphic (i.e., it is not possible to fit your functions in more than one type - it is monomorphic, i.e., having only one type).
There is, however, one particular context, where using 'a
means "I don't care, pick whatever type you want", this is when you're specifying a type constraint, i.e., when you're annotating a parameter of a function or a variable in your let binding, e.g., here 'a
let sum = (x, y): 'a => x + y;
means, "whatever type", despite the fact that it is int
and only int
.
When you provide an annotation (aka type constraint) it is added by the typecheker as an additional constraint to the type equation, for example,
let pair: ('a, 'a) => ('a, 'a) = (x, y) => (x, y);
Here, the function pair
is constrained to be a pair of two equal (unifiable1) types, but those types could be anything, it only matters that they are equal. If we wouldn't add this constraint then the type of the function will be ('a,'b) => ('a,'b)
which is more general.
1)In fact, they are not required to be equal, such constraint just says that x
and y
must be unified, usually, in case of monomorphic types it means, that they should be equal, e.g., int
is only unifiable with int
, but in case of polymoprhic type, especially with subtypes, the least upper bound will be inferred, but this is a completely different story.