+ $ result
+ where
+ var_tys = mkTyVarTys $ tyConTyVars vect_tc
+ arg_ty = mkTyConApp vect_tc var_tys
+ res_ty = reprType repr
+
+ cons = tyConDataCons vect_tc
+ [con] = cons
+
+ to_repr (SumRepr { sum_components = prods
+ , sum_tycon = tycon })
+ expr
+ = do
+ (vars, bodies) <- mapAndUnzipM prod_alt prods
+ return . Case expr (mkWildId (exprType expr)) res_ty
+ $ zipWith4 mk_alt cons vars (tyConDataCons tycon) bodies
+ where
+ mk_alt con vars sum_con body
+ = (DataAlt con, vars, mkConApp sum_con (ty_args ++ [body]))
+
+ ty_args = map (Type . reprType) prods
+
+ to_repr prod expr
+ = do
+ (vars, body) <- prod_alt prod
+ return $ Case expr (mkWildId (exprType expr)) res_ty
+ [(DataAlt con, vars, body)]
+
+ prod_alt (ProdRepr { prod_components = tys
+ , prod_data_con = data_con })
+ = do
+ vars <- mapM (newLocalVar FSLIT("r")) tys
+ return (vars, mkConApp data_con (map Type tys ++ map Var vars))
+
+buildFromPRepr :: Repr -> TyCon -> TyCon -> TyCon -> VM CoreExpr
+buildFromPRepr repr vect_tc prepr_tc _
+ = do
+ arg_ty <- mkPReprType res_ty
+ arg <- newLocalVar FSLIT("x") arg_ty
+
+ liftM (Lam arg)
+ . from_repr repr
+ $ unwrapFamInstScrut prepr_tc var_tys (Var arg)
+ where
+ var_tys = mkTyVarTys $ tyConTyVars vect_tc
+ res_ty = mkTyConApp vect_tc var_tys
+
+ cons = map (`mkConApp` map Type var_tys) (tyConDataCons vect_tc)
+ [con] = cons
+
+ from_repr repr@(SumRepr { sum_components = prods
+ , sum_tycon = tycon })
+ expr
+ = do
+ vars <- mapM (newLocalVar FSLIT("x")) (map reprType prods)
+ bodies <- sequence . zipWith3 from_prod prods cons
+ $ map Var vars
+ return . Case expr (mkWildId (reprType repr)) res_ty
+ $ zipWith3 sum_alt (tyConDataCons tycon) vars bodies
+ where
+ sum_alt data_con var body = (DataAlt data_con, [var], body)
+
+ from_repr repr expr = from_prod repr con expr
+
+ from_prod prod@(ProdRepr { prod_components = tys
+ , prod_data_con = data_con })
+ con
+ expr
+ = do
+ vars <- mapM (newLocalVar FSLIT("y")) tys
+ return $ Case expr (mkWildId (reprType prod)) res_ty
+ [(DataAlt data_con, vars, con `mkVarApps` vars)]
+
+buildToArrPRepr :: Repr -> TyCon -> TyCon -> TyCon -> VM CoreExpr
+buildToArrPRepr repr vect_tc prepr_tc arr_tc
+ = do
+ arg_ty <- mkPArrayType el_ty
+ arg <- newLocalVar FSLIT("xs") arg_ty
+
+ res_ty <- mkPArrayType (reprType repr)
+
+ shape_vars <- arrShapeVars repr
+ repr_vars <- arrReprVars repr
+
+ parray_co <- mkBuiltinCo parrayTyCon
+
+ let Just repr_co = tyConFamilyCoercion_maybe prepr_tc
+ co = mkAppCoercion parray_co
+ . mkSymCoercion
+ $ mkTyConApp repr_co var_tys
+
+ scrut = unwrapFamInstScrut arr_tc var_tys (Var arg)
+
+ result <- to_repr shape_vars repr_vars repr
+
+ return . Lam arg
+ . mkCoerce co
+ $ Case scrut (mkWildId (mkTyConApp arr_tc var_tys)) res_ty
+ [(DataAlt arr_dc, shape_vars ++ concat repr_vars, result)]
+ where
+ var_tys = mkTyVarTys $ tyConTyVars vect_tc
+ el_ty = mkTyConApp vect_tc var_tys
+
+ [arr_dc] = tyConDataCons arr_tc
+
+ to_repr shape_vars@(len_var : _)
+ repr_vars
+ (SumRepr { sum_components = prods
+ , sum_arr_tycon = tycon
+ , sum_arr_data_con = data_con })
+ = do
+ exprs <- zipWithM (to_prod len_var) repr_vars prods
+
+ return . wrapFamInstBody tycon tys
+ . mkConApp data_con
+ $ map Type tys ++ map Var shape_vars ++ exprs
+ where
+ tys = map reprType prods
+
+ to_repr [len_var] [repr_vars] prod = to_prod len_var repr_vars prod
+
+ to_prod len_var
+ repr_vars
+ (ProdRepr { prod_components = tys
+ , prod_arr_tycon = tycon
+ , prod_arr_data_con = data_con })
+ = return . wrapFamInstBody tycon tys
+ . mkConApp data_con
+ $ map Type tys ++ map Var (len_var : repr_vars)
+
+buildFromArrPRepr :: Repr -> TyCon -> TyCon -> TyCon -> VM CoreExpr
+buildFromArrPRepr repr vect_tc prepr_tc arr_tc
+ = do
+ arg_ty <- mkPArrayType =<< mkPReprType el_ty
+ arg <- newLocalVar FSLIT("xs") arg_ty
+
+ res_ty <- mkPArrayType el_ty
+
+ shape_vars <- arrShapeVars repr
+ repr_vars <- arrReprVars repr
+
+ parray_co <- mkBuiltinCo parrayTyCon
+
+ let Just repr_co = tyConFamilyCoercion_maybe prepr_tc
+ co = mkAppCoercion parray_co
+ $ mkTyConApp repr_co var_tys
+
+ scrut = mkCoerce co (Var arg)
+
+ result = wrapFamInstBody arr_tc var_tys
+ . mkConApp arr_dc
+ $ map Type var_tys ++ map Var (shape_vars ++ concat repr_vars)
+
+ liftM (Lam arg)
+ (from_repr repr scrut shape_vars repr_vars res_ty result)