+
+ return . mk_sum $ map (mk_tup . map mk_embed) ess
+
+mkFromPRepr :: CoreExpr -> Type -> [([Var], CoreExpr)] -> VM CoreExpr
+mkFromPRepr scrut res_ty alts
+ = do
+ embed_dc <- builtin embedDataCon
+ cross_dc <- builtin crossDataCon
+ left_dc <- builtin leftDataCon
+ right_dc <- builtin rightDataCon
+ pa_tc <- builtin paTyCon
+
+ let un_embed expr ty var res
+ = Case expr (mkWildId ty) res_ty
+ [(DataAlt embed_dc, [var], res)]
+
+ un_cross expr ty var1 var2 res
+ = Case expr (mkWildId ty) res_ty
+ [(DataAlt cross_dc, [var1, var2], res)]
+
+ un_tup expr ty [] res = return res
+ un_tup expr ty [var] res = return $ un_embed expr ty var res
+ un_tup expr ty (var : vars) res
+ = do
+ lv <- newLocalVar FSLIT("x") lty
+ rv <- newLocalVar FSLIT("y") rty
+ liftM (un_cross expr ty lv rv
+ . un_embed (Var lv) lty var)
+ (un_tup (Var rv) rty vars res)
+ where
+ (lty, rty) = splitCrossTy ty
+
+ un_plus expr ty var1 var2 res1 res2
+ = Case expr (mkWildId ty) res_ty
+ [(DataAlt left_dc, [var1], res1),
+ (DataAlt right_dc, [var2], res2)]
+
+ un_sum expr ty [(vars, res)] = un_tup expr ty vars res
+ un_sum expr ty ((vars, res) : alts)
+ = do
+ lv <- newLocalVar FSLIT("l") lty
+ rv <- newLocalVar FSLIT("r") rty
+ liftM2 (un_plus expr ty lv rv)
+ (un_tup (Var lv) lty vars res)
+ (un_sum (Var rv) rty alts)
+ where
+ (lty, rty) = splitPlusTy ty
+
+ un_sum scrut (exprType scrut) alts