I am porting C# code to F# that makes use of LINQ's Join() extension method. Just as I use that in method call chains, I would of course like to have an F# function to pipe into. However, there is no equivalent in the Seq module, and while the same result could also be achieved with a nested lambda using Seq.where, I'd also want something that tells me by name that it is in fact a join. I came up with this function using a simple query expression:let seqJoin innerKeySelector outerKeySelector resultSelector (innerSequence : 'b seq) (outerSequence : 'a seq) =    query {            for outer in outerSequence do            join inner in innerSequence on                (outerKeySelector outer = innerKeySelector inner)            select (resultSelector outer inner)    }While this works, I'm not sure about the idiomaticity of the API.LINQ's Join() method has this signature:public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(    this IEnumerable<TOuter> outer,    IEnumerable<TInner> inner,    Func<TOuter, TKey> outerKeySelector,    Func<TInner, TKey> innerKeySelector,    Func<TOuter, TInner, TResult> resultSelector)Parameters are 'logically' ordered by importance, the first being the sequence on which the method is (syntactically) called. In F#, in order to be able to pipe the 'original' sequence into the function, that argument needs to be last instead of first, which requires shuffling the whole signature around a bit.In order to keep the two sequences next to each other, I moved innerSequence to the second to last position, and to stay in line with their order, I also switched outerKeySelector and innerKeySelector. I wonder, though, whether once I've changed it that far, it might be more idiomatic to go all the way and make it the full reverse of the C# version, in part because now the resultSelector parameter separates the sequences from their key selector functions and looks a bit out of place in that position. What would be the most 'natural'/idiomatic way to arrange those parameters?As for the query itself, is that the proper way to do it with regards to laziness and expression trees that will be used under the cover? Will the seq type annotations break anything in that respect? Those were necessary to actually allow for using seq and list values as inputs.(This is of course supposed to become an extension for the Seq module; I just haven't bothered to do that yet.)
Join() equivalent function for F# sequences
f#