src/NFun/Interpretation/Functions/GenericFunctionBase.cs
/// <summary>
/// calculates generic call arguments  based on a concrete call signature
/// </summary> 
calculates generic call arguments  based on a concrete call signature
calculates generic call arguments based on a concrete call signature
public FunnyType[] CalcGenericArgTypeList(FunTypeSpecification funTypeSpecification) {
        var result = new FunnyType[Constrains.Length];
        SubstitudeType(ReturnType, funTypeSpecification.Output);
        for (int i = 0; i < funTypeSpecification.Inputs.Length; i++)
        {
            SubstitudeType(ArgTypes[i], funTypeSpecification.Inputs[i]);
        }
        return result;
        bool SubstitudeType(FunnyType genericOrConcrete, FunnyType concrete) {
            var id = genericOrConcrete.GenericId;
            if (id.HasValue)
            {
                result[id.Value] = concrete;
                return true;
            }
            if (genericOrConcrete.ArrayTypeSpecification != null)
                return SubstitudeType(
                    genericOrConcrete.ArrayTypeSpecification.FunnyType,
                    concrete.ArrayTypeSpecification.FunnyType);
            if (genericOrConcrete.FunTypeSpecification != null)
            {
                SubstitudeType(genericOrConcrete.FunTypeSpecification.Output, concrete.FunTypeSpecification.Output);
                for (int i = 0; i < genericOrConcrete.FunTypeSpecification.Inputs.Length; i++)
                {
                    SubstitudeType(
                        genericOrConcrete.FunTypeSpecification.Inputs[i],
                        concrete.FunTypeSpecification.Inputs[i]);
                }
                return true;
            }
            return false;
        }
    }
public FunnyType [ ] CalcGenericArgTypeList ( FunTypeSpecification funTypeSpecification ) { var result = new FunnyType [ Constrains . Length ] ; SubstitudeType ( ReturnType , funTypeSpecification . Output ) ; for ( int i = 0 ; i < funTypeSpecification . Inputs . Length ; i ++ ) { SubstitudeType ( ArgTypes [ i ] , funTypeSpecification . Inputs [ i ] ) ; } return result ; bool SubstitudeType ( FunnyType genericOrConcrete , FunnyType concrete ) { var id = genericOrConcrete . GenericId ; if ( id . HasValue ) { result [ id . Value ] = concrete ; return true ; } if ( genericOrConcrete . ArrayTypeSpecification != null ) return SubstitudeType ( genericOrConcrete . ArrayTypeSpecification . FunnyType , concrete . ArrayTypeSpecification . FunnyType ) ; if ( genericOrConcrete . FunTypeSpecification != null ) { SubstitudeType ( genericOrConcrete . FunTypeSpecification . Output , concrete . FunTypeSpecification . Output ) ; for ( int i = 0 ; i < genericOrConcrete . FunTypeSpecification . Inputs . Length ; i ++ ) { SubstitudeType ( genericOrConcrete . FunTypeSpecification . Inputs [ i ] , concrete . FunTypeSpecification . Inputs [ i ] ) ; } return true ; } return false ; } }
calculates generic call arguments  based on a concrete call signature
calculates generic call arguments based on a concrete call signature
funTypeSpecification
FunTypeSpecification