F#ライブラリに「list.divieat」Hofはありますか? -- .net フィールド と f# フィールド と functional-programming フィールド 関連 問題

Is there any “List.divideAt” HOF in the F# library?












2
vote

問題

日本語

divideAt

を呼び出すことを選択した関数を実装しました <事前> <コード> module List = let divideAt predicate list = let rec divideAt' acc = function | [] -> (List.rev acc, []) | h::_ as ls when predicate h -> (List.rev acc, ls) | h::t -> divideAt' (h::acc) t divideAt' [] list

アイデアは比較的簡単です。リスト内の要素を指定したい場合は、その前にすべての要素を左リストに分離し、その後にすべての要素に別の要素に分離します。

私はリストの上の機能を見て、私は私がこれを実行できるようにすることを可能にするものを見つけることができませんでした。またはそこにいますか?このようにして完全に遅く存在する遅い実装をこのようにすることができます。 <事前> <コード> let divideAt predicate list = match List.tryFindIndex predicate list with | None -> (list, []) | Some(index) -> (List.take index list, List.skip index list)

このHOF実装を使用するときには、「低レベル」再帰アルゴリズムに頼らなければならないことをさらに簡潔に実装できるようなものはありますか?

ありがとう

英語

I implemented a function that I chose to call divideAt:

module List =     let divideAt predicate list =         let rec divideAt' acc = function             | [] -> (List.rev acc, [])             | h::_ as ls when predicate h -> (List.rev acc, ls)             | h::t -> divideAt' (h::acc) t         divideAt' [] list 

The idea is relatively simple: sometimes you want to, given an element in a list, separate all the elements before it into a left list and all the elements after it into another.

I looked all over List's functions and I couldn't find anything that would allow me to do this in a performant way. Or is there? An equivalent, albeit slower implementation relying entirely in high order functions can be accomplished in this way, for instance:

let divideAt predicate list =     match List.tryFindIndex predicate list with     | None -> (list, [])     | Some(index) -> (List.take index list, List.skip index list) 

Is there something that would allow me to implement this even more succinctly without having to rely on the "low level" recursion algorithm yet without having a performance penalty as I have when using this HOF implementation?

Thanks

</div
        

回答リスト

6
 
vote
vote
ベストアンサー
 

私が考えることができる唯一の変更点<コード> List.splitAt はすでに処理されています、取る/スキップ部(おそらくより良い):

<事前> <コード> let divideAt predicate list = match List.tryFindIndex predicate list with None -> list, [] | Some index -> List.splitAt index list

はここで同じことのための別の構文です。関数呼び出しと照合の間にパフォーマンス差があるはずであるとは思わないが、

<事前> <コード> let divideAt predicate list = List.tryFindIndex predicate list |> Option.map (List.splitAt >> (|>) list) |> defaultArg <| (list, [])
 

the only change I can think about is using List.splitAt which already handles, the take/skip part (probably better) :

let divideAt predicate list =   match List.tryFindIndex predicate list with     None       -> list, []   | Some index -> List.splitAt index list 

Alternatively here is another syntax for the same thing ; I don't think there should be a performance difference between function call and match expression but in case :

let divideAt predicate list =   List.tryFindIndex predicate list   |> Option.map (List.splitAt >> (|>) list)   |> defaultArg <| (list, []) 
</div
 
 
       
       
2
 
vote

これは List.partition

で非常に効率的に行うことができます。 <事前> <コード> let divideAt predicate ll = let split = ref false let splitter predicate x = split := !split || (predicate x); !split ll |> List.partition (splitter predicate)

と下記の例のようなもの:

<事前> <コード> > divideAt ((=) 7) [1; 8; 2; 7; 3; 6] val it : int list * int list = ([7; 3; 6], [1; 8; 2])
 

This can be done very efficiently with List.partition:

let divideAt predicate ll =     let split = ref false     let splitter predicate x =         split := !split || (predicate x); !split      ll |> List.partition (splitter predicate) 

and using it like in example below:

> divideAt ((=) 7) [1; 8; 2; 7; 3; 6] val it : int list * int list = ([7; 3; 6], [1; 8; 2]) 
</div
 
 
         
         

関連する質問

1473  モナドとは何ですか?  ( What is a monad ) 
最近、Haskellを簡単に見たことがあるのは、短い、簡潔な、実践的な説明のようなものですか? 私はほとんどの説明を見つけました私はかなりアクセスできなくて実用的な詳細に欠けていることを私が遭遇しました。 ...

93  C ++の関数内の構造とクラスを定義できるのはなぜですか。  ( Why can i define structures and classes within a function in c ) 
私は誤ってC ++でこのようなものをしました、そしてそれはうまくいきます。なぜ私はこれをすることができますか? <事前> <コード> int main(int argc, char** argv) { struct MyStruct { ...

0  文字列を標準ML [DUPLICATE]のリストに変換  ( Convert string to list in standard ml ) 
この質問はすでにここで回答を持っています 閉じられた 10年前。 可能な重複: ml(smlnj) 私はこのような値を持つ文字列値を持っています: <事前> <コード> "[(1,2,3),(2,3),(6,8)]" -> s...

17  Scalaのプレースホルダを持つ文字列に置き換えます  ( Substitute values in a string with placeholders in scala ) 
スカラを使い始め、問題解決への機能的アプローチをよりよく理解したいと思います。 最初にパラメータのプレースホルダーがある文字列のペアがあり、ペアに代わる値があります。例えば 「ID&GT、$ 1と$ 2のような名前のCOL1を選択します。 "パラメータ:$ 1...

33  あなたがまだ変更可能な変数が必要なのを見つけましたか、そしてそれであればなぜ?  ( Do you find you still need variables you can change and if so why ) 
機能言語に対して聞いた引数の1つは、単一の割り当てコーディングが難しすぎる、または「通常の」プログラミングよりも少なくとも大幅に困難なことです。 しかし私のコードを通して見ることは、私は本当に(任意の?)必要とされていないパターンを使用できないことに気付くこと...

101  HASKELL構成(。)VS#のパイプフォワードオペレーター(|>)  ( Haskell composition vs fs pipe forward operator ) 
f#では、パイプフォワードオペレータの使用、<コード> 9988766610 はかなり一般的です。しかし、Haskellでは、 998877611 を使用した機能構成を見たことがあります。私は関連であることを理解しています。パイプフォワードがHaskellで...

6  機能言語は複雑さでよく対処しますか?  ( Do functional languages cope well with complexity ) 
私は、大規模なプログラムのためのC#やJavaなどのより「伝統的な」言語にどのような機能を比較するか(一般的に)どのように興味があるか。機能的な言語が使用されていない場合よりもプログラムの流れが早く従うのが難しくなりますか?機能言語を使って大型ソフトウェアプロ...

34  良いClojureベンチマークはありますか?  ( Are there any good clojure benchmarks ) 
編集: Clojureベンチマークはベンチマークゲーム 。 私はこの質問コミュニティWikiを作り、他の人を更新し続けるように勧めました。 は、Clojureのパフォーマンスのベンチマークを認識していますか? 私は自分のものをいくつかしました(正式な...

103  現実の世界で機能的なプログラミングをどのように使用できますか? [閉まっている]  ( How can i use functional programming in the real world ) 
閉鎖。この質問はもっと焦点を絞ったにする必要があります。現在答えを受け付けていません。 この質問を改善したいですか? ...

162  Haskellのマルチコアプログラミングの状況は何ですか?  ( Whats the status of multicore programming in haskell ) 
Haskellのマルチコアプログラミングの状況は何ですか?今すぐプロジェクト、ツール、およびライブラリを利用できますか?どの経験報告がありましたか? ...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有