public Estimator <TTupleInShape, TTupleNewOutShape, ITransformer> Append <[IsShape] TTupleNewOutShape>(Func <TTupleOutShape, TTupleNewOutShape> mapper) { Contracts.CheckValue(mapper, nameof(mapper)); using (var ch = Env.Start(nameof(Append))) { var method = mapper.Method; // Construct the dummy column structure, then apply the mapping. var input = StaticPipeInternalUtils.MakeAnalysisInstance <TTupleOutShape>(out var fakeReconciler); KeyValuePair <string, PipelineColumn>[] inPairs = StaticPipeInternalUtils.GetNamesValues(input, method.GetParameters()[0]); // Initially we suppose we've only assigned names to the inputs. var inputColToName = new Dictionary <PipelineColumn, string>(); foreach (var p in inPairs) { inputColToName[p.Value] = p.Key; } string NameMap(PipelineColumn col) { inputColToName.TryGetValue(col, out var val); return(val); } var readerEst = StaticPipeUtils.GeneralFunctionAnalyzer(Env, ch, input, fakeReconciler, mapper, out var estTail, NameMap); ch.Assert(readerEst == null); ch.AssertValue(estTail); var est = AsDynamic.Append(estTail); var newOut = StaticSchemaShape.Make <TTupleNewOutShape>(method.ReturnParameter); var toReturn = new Estimator <TTupleInShape, TTupleNewOutShape, ITransformer>(Env, est, _inShape, newOut); ch.Done(); return(toReturn); } }