public static BasicMapRead mapRead(IEnumerable <IType> typeArguments, IEnumerable <IType> argumentTypes, IType resultType)
        {
            Debug.Assert(typeArguments != null);
            Debug.Assert(argumentTypes != null);
            Debug.Assert(argumentTypes.Count() > 0);
            var mapType = argumentTypes.First() as MapType;

            Debug.Assert(mapType != null);
            Debug.Assert(typeArguments.Count() == mapType.typeParameters.Length);
            Debug.Assert(mapType.domain.Count() == argumentTypes.Count() - 1);

            var   substitution = new TypeParameterInstantiation(mapType.typeParameters, typeArguments);
            IType sresultType  = mapType.range.substitute(substitution);

            Debug.Assert(resultType.ToStringN() == sresultType.ToStringN());
            Debug.Assert(argumentTypes.Skip(1).Zip(mapType.domain, (at, mtD) => at.isEquivalent(mtD.substitute(substitution))).All(x => x));
            string indexString = makeIndexString(TypeTuple.make(typeArguments), TypeTuple.make(argumentTypes));

            BasicMapRead result = null;

            bool foundInstance = instances.TryGetValue(indexString, out result);

            if (result != null)
            {
                if (!ReferenceEquals(resultType, result.resultType))
                {
                    foundInstance = false;
                }
                else
                if (argumentTypes.Zip(result.argumentTypes, (x, y) => x.isEquivalent(y)).Any(x => !x))
                {
                    foundInstance = false;
                }
            }
            if (!foundInstance)
            {
                var indexTypes = argumentTypes.Skip(1);
                result = new BasicMapRead(mapType, typeArguments, indexTypes, resultType);
                instances[indexString] = result;
            }
            return(result);
        }
 public MapRead mapRead(IEnumerable <IType> mapTypeArgs)
 {
     Debug.Assert(mapTypeArgs.Count() == mapType.typeParameters.Length);
     return(BasicMapRead.mapRead(mapType, TypeTuple.make(mapTypeArgs)));
 }