fn unroll_values(
    parameters: &[Parameter],
    value: &Expr,
    vectors: &[Expr],
    loopsize: u64,
) -> WeldResult<Vec<Expr>> {
    if parameters.len() != 3 {
        return compile_err!("Expected three parameters to Merge function");
    }

    let index_symbol = &parameters[1].name;
    let elem_symbol = &parameters[2].name;
    let elem_ident = &Expr::new_ident(elem_symbol.clone(), parameters[2].ty.clone())?;

    let mut expressions = vec![];
    for i in 0..loopsize {
        let mut unrolled_value = value.clone();
        unrolled_value.transform(&mut |ref mut e| {
            match e.kind {
                Ident(ref name) if name == index_symbol => {
                    // Index identifiers can be handled by just substituting a static index.
                    Some(Expr::new_literal(LiteralKind::I64Literal(i as i64)).unwrap())
                }
                Ident(ref name) if name == elem_symbol && vectors.len() == 1 => {
                    // There is a single iterator, which means the type of the element is the type
                    // of the iterator's data. Replace it with a lookup into the vector.
                    Some(
                        Expr::new_lookup(
                            vectors[0].clone(),
                            Expr::new_literal(LiteralKind::I64Literal(i as i64)).unwrap(),
                        )
                        .unwrap(),
                    )
                }
                GetField {
                    ref expr,
                    ref index,
                } if is_same_ident(expr, elem_ident) && vectors.len() > 1 => {
                    // There are multiple iterators zipped into a struct, and this expression is
                    // pulling one of the elements out of that struct. Replace it with a lookup into the vector.
                    let data_expr = vectors[*index as usize].clone();
                    Some(
                        Expr::new_lookup(
                            data_expr,
                            Expr::new_literal(LiteralKind::I64Literal(i as i64)).unwrap(),
                        )
                        .unwrap(),
                    )
                }
                _ => None,
            }
        });
        expressions.push(unrolled_value);
    }
    Ok(expressions)
}
Takes a `MergeSingle` and returns a list of expressions which replace the element
in the merge with a Lookup.
weld/src/optimizer/transforms/unroller.rs