+ left_dc <- builtin leftDataCon
+ right_dc <- builtin rightDataCon
+ pa_tc <- builtin paTyCon
+
+ let un_embed expr ty var res
+ = do
+ pa <- newLocalVar FSLIT("pa") (mkTyConApp pa_tc [idType var])
+ return $ Case expr (mkWildId ty) res_ty
+ [(DataAlt embed_dc, [pa, 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 = 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