2
 for i in a..b do
     res <- res * myarray.[i]
 res

のように使用する必要がありますか

  Array.fold (*) 1 (Array.sub myarray a (b - a + 1))

、これはかなり遅く、それほど簡潔ではないと思いますか?

4

3 に答える 3

5

あなたがそれをもっと良くするかどうかはわかりませんが、あなたはできるでしょう:

Seq.fold (fun r i -> r * myarray.[i]) 1 {a .. b}
于 2012-09-19T15:59:30.387 に答える
4

forダニエルのソリューションは非常に優れており、配列を複製する必要がないため、ループとほぼ同じくらい効率的であると思います。

より簡潔なソリューションArray.subが必要な場合は、配列の一部を複製する必要がある の代わりにインデクサーを使用できますが、非常にきれいに見えます。

myarray.[a .. b] |> Seq.fold (*) 1

スライス操作は配列を返すため、これは配列の一部を複製します。要素を次のように返す独自のスライス操作を定義できますseq<'T>(したがって、配列全体を複製しません)。

module Array =
  let slice a b (arr:'T[]) = 
    seq { for i in a .. b -> arr.[i] }

この関数を使用すると、次のように記述できます。

myarray |> Array.slice a b |> Seq.fold (*) 1

これは、実装しようとしている機能をより直接的に表現していると思います。パフォーマンスと同様に、パフォーマンスを測定して、そのような最適化を行う必要があるかどうか、または最初のバージョンが目的に対して十分に高速であるかどうかを確認する必要があります。

于 2012-09-19T16:47:33.873 に答える
4

If you're concerned with speed then I'd shy away from using seq unless you're prototyping. Either stick with the for loop or rewrite as a recursive function. The example you gave is simplistic and sometimes more complex problems are better represented as recursion.

let rec rangeProduct a b total (array : _[]) =
    if a <= b then
        rangeProduct (a + 1) b (total * array.[a]) array
    else
        total

let res = myArray |> rangeProduct a b res

There is no overhead here, it's as fast as possible, there is no mutation, and it's functional.

于 2012-09-19T17:36:38.663 に答える