public static MonadOr <TResult> Join <TSource, TInner, TKey, TResult>( this MonadOr <TSource> @this, MonadOr <TInner> inner, Func <TSource, TKey> outerKeySelector, Func <TInner, TKey> innerKeySelector, Func <TSource, TInner, TResult> resultSelector, IEqualityComparer <TKey> comparer) { Require.NotNull(@this, nameof(@this)); Require.NotNull(inner, nameof(inner)); Require.NotNull(resultSelector, nameof(resultSelector)); Require.NotNull(outerKeySelector, nameof(outerKeySelector)); Require.NotNull(innerKeySelector, nameof(innerKeySelector)); var lookup = GetKeyLookup(inner, innerKeySelector, comparer); Func <TSource, MonadOr <TInner> > valueSelector = outer => lookup(outerKeySelector(outer)); return(@this.SelectMany(valueSelector, resultSelector)); }