## Unboxed tuples with multiplicity parametric fields

## Motivation

Currently, an unboxed tuple always have all fields linear. This is fine for most purpose but it actually does hamper optimisations. This is a problem which only happens on code using `-XLinearTypes`

, therefore it's not too serious, but still we ought to make good by it.

Specifically, it concerns the CPR transformation when the returned argument has an unrestricted field (*e.g.* the `Unrestricted`

datatype which has a single unrestricted field). The story is expounded in the wiki page. Let me copy the explanation here.

Consider a function

`f :: Int -> Unrestricted A`

The argument type doesn't matter, the result type does.

The CPR split yields:

```
$wf :: Int -> (# A #)
f x = case_1 $wf x of
(# y #) -> Unrestricted y
```

This is ill-typed unless `(# #)`

has an unrestricted field (currently, all fields of an unboxed tuple are linear).

Therefore, CPR is restricted to the case where the constructor only has linear field.

## Proposal

To be able to activate the CPR worker/wrapper split on data types with an unrestricted field, unboxed tuple should be parametrised by the multiplicity of their field, that is

```
type (#,#) :: forall r s. Multiplicity -> Multiplicity -> TYPE r -> TYPE s -> TYPE …
data (#,#) p q a b where
(#,#) :: a #p-> b #q-> (#,#) p q a b
```

At least the unboxed tuples used by Core should have such a type. It can also be a user-facing feature.

### Alternative

An alternative is to have a single additional unboxed data type

```
data Unrestricted# a where
Unrestricted# :: a -> Unrestricted# a -- unrestricted field
```

And we could use `(# a, Unrestricted# b #)`

in CPR as the unboxed stand in for a data type which is linear in its first field and unrestricted in its second field.