'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 |
