---
# System prepended metadata

title: Unboxed Tuple

---

# Unboxed Tuple

```hs
-- Type constructor
type (# , #) :: forall (r1 :: RuntimeRep)  (r2 :: RuntimeRep)
                       (v1 :: CallingConv) (v2 :: CallingConv).
                TYPE (RInfo r1 v1) -> TYPE (RInfo r2 v2)
             -> TYPE (RInfo (TupleRep [r1, r2]) ConvEval)
                

-- Data constructor
(# , #) :: forall (r1 :: RuntimeRep)  (r2 :: RuntimeRep)
                  (v1 :: CallingConv) (v2 :: CallingConv).
                  (a :: TYPE (RInfo r1 v1))
                  (b :: TYPE (RInfo r2 v2)).
           a -> b -> (# , #) r1 r2 v1 v2 a b
```


``` hs
mk_tuple Unboxed arity = (tycon, tuple_con)
  where
    tycon = mkTupleTyCon tc_name tc_binders tc_res_kind tc_arity tuple_con
                         UnboxedTuple flavour

    -- See Note [Unboxed tuple RuntimeRep vars] in GHC.Core.TyCon
    -- Kind:  forall (k1:RuntimeRep) (k2:RuntimeRep). TYPE k1 -> TYPE k2 -> #
    tc_binders = mkTemplateTyConBinders (replicate arity runtimeInfoTy)
                                        (\ks -> map tYPE ks)
```
>     The above call to mkTemplateTyConBinders is what creates the kind var's
> 
>     forall (r1 :: RuntimeRep)  (r2 :: RuntimeRep)
>                   (v1 :: CallingConv) (v2 :: CallingConv).
>                   (a :: TYPE (RInfo r1 v1))
>                   (b :: TYPE (RInfo r2 v2))

```

    tc_res_kind = unboxedTupleKind rr_tys

    tc_arity    = arity * 2
    flavour     = UnboxedAlgTyCon $ Just (mkPrelTyConRepName tc_name)

    dc_tvs               = binderVars tc_binders
    (rr_tys, dc_arg_tys) = splitAt arity (mkTyVarTys dc_tvs)
    tuple_con            = pcDataCon dc_name dc_tvs dc_arg_tys tycon

    boxity  = Unboxed
    modu    = gHC_PRIM
    tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq
                         (ATyCon tycon) BuiltInSyntax
    dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq
                            (AConLike (RealDataCon tuple_con)) BuiltInSyntax
    tc_uniq = mkTupleTyConUnique   boxity arity
    dc_uniq = mkTupleDataConUnique boxity arity
```
```
mkTemplateTyConBinders
    :: [Kind]                -- [k1, .., kn]   Kinds of kind-forall'd vars
    -> ([Kind] -> [Kind])    -- Arg is [kv1:k1, ..., kvn:kn]
                             --     same length as first arg
                             -- Result is anon arg kinds
    -> [TyConBinder]
mkTemplateTyConBinders kind_var_kinds mk_anon_arg_kinds
  = kv_bndrs ++ tv_bndrs
  where
    kv_bndrs   = mkTemplateKindTyConBinders kind_var_kinds
    anon_kinds = mk_anon_arg_kinds (mkTyVarTys (binderVars kv_bndrs))
    tv_bndrs   = mkTemplateAnonTyConBindersFrom (length kv_bndrs) anon_kinds

mkTemplateKindTyConBinders :: [Kind] -> [TyConBinder]
-- Makes named, Specified binders
mkTemplateKindTyConBinders kinds = [mkNamedTyConBinder Specified tv | tv <- mkTemplateKindVars kinds]
```