public static IEnumerable <IError> Validate(IOrType <IBox <IFrontendCodeElement>, IError> input, IOrType <IBox <IFrontendCodeElement>, IError> method) { var inputTypeOrErrors = input.ReturnsTypeOrErrors(); var methodInputTypeOrErrors = method .ReturnsTypeOrErrors() .TransformAndFlatten(thing => thing.TryGetInput().SwitchReturns(orType => orType, no => { return(OrType.Make <IFrontendType <IVerifiableType>, IError>(Error.Other($"{thing} should return"))); } , error => OrType.Make <IFrontendType <IVerifiableType>, IError>(error))); return(inputTypeOrErrors.SwitchReturns( i => methodInputTypeOrErrors.SwitchReturns <IEnumerable <IError> >( mi => { if (!i.TheyAreUs(mi, new List <(IFrontendType <IVerifiableType>, IFrontendType <IVerifiableType>)>()).SwitchReturns(x => x, x => false)) { return new[] { Error.Other($"{method} does not accept {input}") }; } return Array.Empty <IError>(); }, mi => { return new IError[] { mi }; }), i => methodInputTypeOrErrors.SwitchReturns <IEnumerable <IError> >( m => { return new IError[] { i }; }, m => { return new IError[] { i, m }; }))); }
public static IOrType <IFrontendType <IVerifiableType>, IError> Returns(IOrType <IBox <IFrontendCodeElement>, IError> method) { return(method.ReturnsTypeOrErrors().TransformAndFlatten(thing => { if (thing is SyntaxModel.Elements.AtomicTypes.MethodType method) { return method.OutputType.GetValue(); } return OrType.Make <IFrontendType <IVerifiableType>, IError>(Error.Other($"{thing} should return")); })); }