I would say it depends on how your functions are intended to be used. From my point of view, the general form of a function’s type is a -> b
, i.e. it is something that transforms an object of type a
to an object of type b
: a morphism. So when I see a function with the type a -> b -> c
, I see it as a family of morphisms from type b
to type c
parametrized by a value of type a
. Therefore, if you want a family of morphisms that operate on your type t
, you put it last, but if it is your type that parameterized a family of morphisms (as with regex for instance) you put it first.
If I take this two examples from the standard lib:
List.map;;
- : ('a -> 'b) -> 'a list -> 'b list = <fun>
List.nth;;
- : 'a list -> int -> 'a = <fun>
I consider the first one has a good type: we transform a morphism from a
to b
to a morphism from a list
to b list
(the type constructor list
is a functor, and map
is the fmap
of the functor type classes in Haskell). But for the second one, I would gave it the type int -> 'a list -> 'a
considering this is only a generalization of hd : 'a list -> 'a
(== List.nth 1
).