'Split list of tuples into different partitions in ML

I've done Python for quite awhile and what I'm trying to achieve should've been identical but I'm running into a pesky error.

My problem is that I would like a list of tuples in ML split into separate variables.

val myList = [(1,2),(3,4)];
val (x :: y) = myList;

In the above statement x would be (1,2) and y would be (3,4), ... [If there was anymore]. Simple enough.

Now I want to introduce a third variable z where z would be (3,4),... and x, y would be (1,2) respectfully.

val myList = [(1,2),(3,4)];
val ((x :: y) :: z) = myList;

The error produced by the previous snippet is:

error: Pattern and expression have incompatible types.
Pattern: ((x :: y) :: z) : 'a list list
   Expression: myList : (int * int) list
   Reason: Can't unify 'a list to int * int (Incompatible types)

Edit: As requested, this is what z should achieve.

val myList = [(1,2),(3,4)];
val ((x :: y) :: z) = myList;

Output would be: x = 1, y = 2, z = (3,4)

In Python this would be:

Python 3.9.6 | packaged by conda-forge | (default, Jul 11 2021, 
03:35:11) 
[Clang 11.1.0 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> (x,y),z = [(1,2),(3,4)]
>>> x
1
>>> y
2
>>> z
(3, 4)


Solution 1:[1]

Upon further investigation, :: doesn't denote a comma where as in Python I would've used one. Switching between the two solves this:

val ((x :: y) :: z) = myList;

Now becomes:

val ((x, y), z) = myList;

Solution 2:[2]

Your first snippet doesn't do what you think it does:

val myList = [(1, 2), (3, 4)];
val (x :: y) = myList;

The pattern x :: y binds x to the head of the list (in this case, (1, 2)), and y to the tail of the list (in this case, [(3, 4)], not (3, 4)). If you want to extract the first two elements, do this:

val myList = [(1, 2), (3, 4)];
val x :: y :: z = myList;

x will be bound to (1, 2), the tail will again be pattern-matched so that y is bound to (3, 4), and z to the empty list [].

To pattern-match the pieces in a pair (2-tuple), use (x, y). The following should achieve what you want:

val myList = [(1, 2), (3, 4)];
val (x, y) :: z :: _ = myList;
(* x: 1
 * y: 2
 * z: (3, 4)
 *)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kyle J
Solution 2 ElectroQt