Search code examples
standardssmlsmlnjml

Syntax for a function with (’a * ’b) list → (’b * ’a) list


I am trying to write a function to swap a pair of tuples inside of a list like this:

- pairSwap [(1, 2), (3, 4), (5, 6);
 [(2,1),(4,3),(6,5)]

I am having a hard time figuring out what I am doing wrong with my syntax while declaring the function. This is what I have so far:

fun pairSwap ((a : 'a, b: 'a) list) : (('a, 'a) list) = 
...
;

Where am I going wrong?

Edit: Solution

fun pairSwap (t : ('a * 'a) list) : ('a * 'a) list = 
  if null t
    then []
  else
    let
      val v = hd t
    in
      (#2 v, #1 v)::pairSwap (tl t)
    end
;

Solution

  • Since you have provided a solution in the meantime, here is some feedback on it:

    • You don't really need the type annotations. You can let type inference do the work.

      fun pairSwap t = ...
      
    • You can use null, hd and tl, but consider pattern matching:

      fun pairSwap [] = []
        | pairSwap ((x,y)::ps) = (y,x)::pairSwap ps
      

      This also makes the let-expression redundant.

    • As Matt points out, the type for this function is ('a × 'b) list → ('b × 'a) list, which means you can also swap pairs where the left side has a different type ('a) than the right side ('b), e.g.:

      - pairSwap [("hello",42),("world",43)];
      val it = [(42,"hello"),(43,"world")] : (int * string) list