MLton and polymorphic recursion through datatypes?
Matthew Fluet
Matthew Fluet <fluet@CS.Cornell.EDU>
Tue, 17 Apr 2001 10:06:30 -0400 (EDT)
> > I haven't seen any program which makes use of this feature of SML.
>
> Me neither.
The problem, I think, is that datatypes with polymorphic recursion are of
limited use when you can't (easily) write functions with polymorphic
recursion. For example, with the alternating list datatype
datatype ('a, 'b) altlist = nil | cons of 'a * ('b, 'a) altlist
you would like to write the map function with the type:
('a -> 'c) -> ('b -> 'd) -> ('a, 'b) altlist -> ('c, 'd) altlist
The simplest function one might like to write is the following:
fun altmap fa fb
= fn nil => nil
| cons (h, t) => cons (fa h, altmap fb fa t)
which does typecheck, but gives you an overly restricted type:
('a -> 'b) -> ('a -> 'b) -> ('a,'a) altlist -> ('b,'b) altlist
because the SML type system requires all occurrences of a recursively
defined function to be used monomorphically inside the body of the
definition.
You can get around this by "unrolling" the recursion manually:
fun altmapA fa fb
= fn nil => nil
| cons (h, t) => cons (fa h, altmapB fb fa t)
and altmapB fb fa
= fn nil => nil
| cons (h, t) => cons (fb h, altmapA fa fb t)
val altmap = altmapA
But, IMHO, you're left somewhat annoyed by the fact that you needed to
write almost syntactically identical functions to satisfy the type system.