2

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)

Community
  • 1
  • 1
asaelr
  • 5,438
  • 1
  • 16
  • 22

1 Answers1

3

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])
Matt
  • 4,029
  • 3
  • 20
  • 37