5

Is there a more idiomatic way to express this pattern in F#:

seq {
    for item1 in list1 do 
        for item2 in list2 do
            yield f(item1,item2)
}

Thanks!

Robert Sim
  • 1,428
  • 11
  • 22

2 Answers2

6

This pattern is as idiomatic as it gets.

Usually an alternative is to use a pipeline of higher-order functions like Seq.map or Seq.filter, but for your particular case - Cartesian product - a sequence comprehension approach really shines and you won't get anything near that simple otherwise.

Utlimately it's a judgement call which style to use. I tend to prefer the pipeline approach, only to later realize how much clearer a sequence comprehension approach is.

scrwtp
  • 13,437
  • 2
  • 26
  • 30
  • 1
    just as a comment - you need `Seq.collect` or `Seq.concat` (the monadic methods) to *translate* something with more than one `for` in it (should be the case as it makes no sense to use `seq { ... }` over a simple `map` or `filter` otherwise. – Random Dev Apr 14 '15 at 04:35
  • 1
    @CarstenKönig: true - an actual example of how to implement it using `Seq.map` nested in `Seq.collect` is in the linked thread. As for not using comprehensions for simple mapping/filtering - I think there are some who would disagree (I think Tomas Petricek recently wrote that he prefers that style). – scrwtp Apr 14 '15 at 10:04
1

As long, as you don't need anything complicated, like imperative features or flattening of sub-expressions (yield!), you can use a slightly less verbose syntax:

seq { for item1 in list1 do
      for item2 in list2 -> f(item1, item2) }
Daniel Fabian
  • 3,828
  • 2
  • 19
  • 28