おまけ

ついでに、良く使う範囲での ScalaC# のリスト操作対応表。

Scala C#
map Select
flatMap SelectMany
filter Where
foldLeft Aggregate *1
foldRight なし
reduceLeft Aggregate *2
reduceRight なし
foreach なし
zip Zip *3

すぐに思いつくのは、この辺りぐらい。Skip とか Take、TakeWhile あたりもあったはず。あとは Single とか First とかかな。
collect が無いのはわりと不便に感じることが多い。C# には PartialFunction が無いのでしょうがないのだろうけど。あと、partition も無い気がする。これは作ってもいいんじゃないかなぁ?と思う。遅延リストにするのは難しいのかもだけど。


そうそう、遅延リスト。これについては C# の方が数段便利だと感じてる。遅延リスト・・・というか、IEnumerable を実装するのがものすごい簡単。基本はメソッドから値を返すときに yield return すれば、あとはよしなにやってくれるので、実装の手間がものすごい少ないです。しかも、遅延リストになる。
たとえば、Select だけれども、自分で実装するなら以下のようなコードでよい。

public static class EnumerableExtensions
{
  public static IEnumerable<U> Select<T, U>(this IEnumerable<T> src, Func<T, U> func)
  {
    foreach (var value in src)
      yield return func(value);
  }
}

これだけで、yield return の各戻り値を要素として取り出せる IEnumerable のインスタンスを返すことが出来る。
ちなみに、yield return は繰り返し構文の中でなくとも使える。例えば、以下だと 1, 2, 3 を要素とする IEnumerable が得られる。

public IEnumerable<int> GetValues()
{
  yield return 1;
  yield return 2;
  yield return 3;
}

戻り値は IEnumerable でなくても IEnumerator でもOKだったような気もする。ちなみにどちらであっても、次の要素が必要となったときに、メソッドの実行が続行されるようです。なので、無限リストを作成するのも簡単にできると思います。

public IEnumerable<int> Start(int start)
{
  for(var i=start;; i++)
    yield return i;
}

Scala の場合、Stream をつかって、ほげほげしないといけないので、ちょっと面倒です。

追記

id:bleis-tift さんの指摘をうけて、対応表の Zip 他に注釈を追加しました。

*1:seedの引数あり

*2:seedの引数無し

*3:第二引数に Tuple.Create を指定