- cross_tc <- builtin crossTyCon
- cross_dc <- builtin crossDataCon
-
- let mk (left, left_ty) (right, right_ty)
- = (mkConApp cross_dc [Type left_ty, Type right_ty, left, right],
- mkTyConApp cross_tc [left_ty, right_ty])
-
- return . fst
- $ foldr1 mk [(expr, exprType expr) | expr <- exprs]
+ embed_dc <- builtin embedDataCon
+ sum_tcs <- builtins sumTyCon
+ prod_tcs <- builtins prodTyCon
+
+ let un_sum expr ty [(vars, res)] = un_prod expr ty vars res
+ un_sum expr ty bs
+ = do
+ ps <- mapM (newLocalVar FSLIT("p")) tys
+ bodies <- sequence
+ $ zipWith4 un_prod (map Var ps) tys vars rs
+ return . Case expr (mkWildId ty) res_ty
+ $ zipWith3 mk_alt sum_dcs ps bodies
+ where
+ (vars, rs) = unzip bs
+ tys = splitFixedTyConApp sum_tc ty
+ sum_tc = sum_tcs $ length bs
+ sum_dcs = tyConDataCons sum_tc
+
+ mk_alt dc p body = (DataAlt dc, [p], body)
+
+ un_prod expr ty [] r = return r
+ un_prod expr ty [var] r = return $ un_embed expr ty var r
+ un_prod expr ty vars r
+ = do
+ xs <- mapM (newLocalVar FSLIT("x")) tys
+ let body = foldr (\(e,t,v) r -> un_embed e t v r) r
+ $ zip3 (map Var xs) tys vars
+ return $ Case expr (mkWildId ty) res_ty
+ [(DataAlt prod_dc, xs, body)]
+ where
+ tys = splitFixedTyConApp prod_tc ty
+ prod_tc = prod_tcs $ length vars
+ [prod_dc] = tyConDataCons prod_tc