for i in a..b do
res <- res * myarray.[i]
res
のように使用する必要がありますか
Array.fold (*) 1 (Array.sub myarray a (b - a + 1))
、これはかなり遅く、それほど簡潔ではないと思いますか?
for i in a..b do
res <- res * myarray.[i]
res
のように使用する必要がありますか
Array.fold (*) 1 (Array.sub myarray a (b - a + 1))
、これはかなり遅く、それほど簡潔ではないと思いますか?
あなたがそれをもっと良くするかどうかはわかりませんが、あなたはできるでしょう:
Seq.fold (fun r i -> r * myarray.[i]) 1 {a .. b}
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
これは、実装しようとしている機能をより直接的に表現していると思います。パフォーマンスと同様に、パフォーマンスを測定して、そのような最適化を行う必要があるかどうか、または最初のバージョンが目的に対して十分に高速であるかどうかを確認する必要があります。
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.