私は関数型プログラミングの方法を考える方法を学ぼうとしています。そのために、私はErlangを学び、codingbatから簡単な問題を解決しようとしています。リスト内の要素を比較するという共通の問題が発生しました。たとえば、i番目の位置要素の値とリストのi + 1番目の位置の値を比較します。だから、私はErlang(または任意の関数言語)の機能的な方法でこれを行う方法を考えて、探しています。
してください、私と優しい、私はこの機能的な世界では非常にnewbですが、私は学びたい
前もって感謝します
リストを定義する:
L = [1,2,3,4,4,5,6]
リストを取る関数fを定義する
Erlangコード
f ([]) -> [];
f ([_]) -> [];
f ([X, X|Rest]) -> [X | f(Rest)];
f ([_|Rest]) -> f(Rest).
適用機能
f(L)
これはうまくいくはずだ...コンパイルして実行していないが、それを開始する必要があります。また、それを変更して別の振る舞いをする必要がある場合に備えてください。
Erlangへようこそ;)
私は穏やかにしようとします;-)機能的なアプローチの主なものは、考え方です:入力は何ですか?何が出力されるべきですか? i番目の要素とi + 1番目の要素だけを比較するようなものはありません。常にデータの変換につながる目的がなければなりません。たとえ Mazen Harake の例でもそうしています。この例では、同じ値が後に続く要素、すなわちリストを与えられたフィルタのみを返す関数があります。典型的には、それの目的に依存する類似のことをどのように行うかは非常に異なる方法があります。リストは基本的な関数構造であり、Lispが私たちに示したように素晴らしいことをすることができますが、配列ではないことを覚えておく必要があります。
繰り返しアクセス可能なi番目の要素にアクセスする必要があるたびに、間違ったデータ構造を使用していることを示します。 Erlangではリストやタプルなどさまざまなデータ構造を構築することができ、目的に合ったものにすることができます。ですから、i番目とi + 1番目の要素を比較する問題に直面したときは、停止して考える必要があります。それの目的は何ですか? Mazen Harake のようにストリームデータ変換を実行する必要があるか、ランダムアクセスが必要です? 2番目の場合は、別のデータ構造(配列など)を使用する必要があります。それでもあなたの仕事の特徴について考えるべきです。大部分が読み込まれほとんど書くことができない場合は、 list_to_tuple(L)
を使用して element/2
を使用して読むことができます。時折書く必要があるときは、それをいくつかのタプルに分割することを考え始めるでしょう。あなたの書き込み比率が大きくなると、 array
の実装になります。
したがって、1回か数回だけですが、短いリストで、あなたが私のようにパフォーマンスの狂気でないなら、 lists:nth/2
を使うことができます。 [X1、X2 | _] =リスト:nthtail(I-1、L)
( L =リスト:nthtail(0、L)
期待される)。より大きなリストに直面していて、何度も呼びたい場合は、アプローチを再考する必要があります。
P.S .:リストやツリーを除く他の多くの魅力的なデータ構造があります。ジッパーなど。