I know you can do stuff like:
@type pair(t, u) :: {t, u}
@type result(t, e) :: {:ok, t} | {:error, e}
I'm more talking about type parameters on functions, and also constraining by behaviors and protocols. For example the typespec for Elixir's Stream.map/2 (
http://elixir-lang.org/docs/stable/elixir/Stream.html#map/2):
@spec map(Enumerable.t, (element -> any)) :: Enumerable.t
Note all the other similarly unspecific type definitions. In a parametrically polmorphic lang, you could do something like:
@spec map[e1: Enumerable, e2: Enumerable](e1.t, (e1.element -> e2.element)) :: e2.t
And perhaps even intersections of behaviours and protocols:
@spec foo[a: Eq & Ord](a.t, a.t) :: bool
('scuse the Elixir syntax...)