Is there a way, to write a polymorphic function (in sml), that calls itself with arguments of different type than the arguments it has got?
For example, I was looking on this answer, (it has the declaration datatype ('a,'b)alterlist = Nil| element of 'a*('b,'a)alterlist;
) and intuitively, I would like to implement the function unzip
, as:
fun unzip Nil = ([],[]) |
unzip (element(x,l)) = let val (b,a)=unzip l in (x::a,b) end;
The type inference system understands it as ('a,'a) alterlist -> 'a list * 'a list
, but I want something of type ('a,'b) alterlist -> 'a list * 'b list
(such that the inner call is to a ('b,'a) alterlist -> 'b list * 'a list
)
I believe what you are asking for is polymorphic recursion, which is not implemented in standard ML.
This is however implemented in Haskell (and as @seanmcl pointed out, ocaml):
import Prelude hiding(unzip)
data Alterlist a b = Nil | Elem a (Alterlist b a)
unzip :: Alterlist a b -> ([a], [b])
unzip Nil = ([], [])
unzip (Elem x l) =
let (b, a) = unzip l
in (x : a, b)
x = Elem 1 (Elem True (Elem 5 (Elem False Nil)))
*Main> unzip x
([1,5],[True,False])