scala に関する本を読み終えました。私を驚かせたのは、本全体のすべての例が何らかの形で数値であったということです.
多くのプログラマーと同じように、私が使用する唯一の数学は離散数学と組み合わせ数学からのものであり、通常、明示的な方法でプログラムする数学ではありません。通常のooアルゴリズムに対する機能的な代替/補足のいくつかの説得力のある例が本当に欠けています。
関数型プログラミングの数値以外のユースケースにはどのようなものがありますか?
scala に関する本を読み終えました。私を驚かせたのは、本全体のすべての例が何らかの形で数値であったということです.
多くのプログラマーと同じように、私が使用する唯一の数学は離散数学と組み合わせ数学からのものであり、通常、明示的な方法でプログラムする数学ではありません。通常のooアルゴリズムに対する機能的な代替/補足のいくつかの説得力のある例が本当に欠けています。
関数型プログラミングの数値以外のユースケースにはどのようなものがありますか?
会社から、ユーザーがフラット ファイル データベースに対してアドホック クエリを実行できるカスタム アプリケーションを作成するように依頼されました。このアプリのユーザーは、典型的なジョー ビジネスマン タイプでした。彼らはプログラマーではなく、人生で SQL ステートメントを見たことがありません。
その結果、ユーザーが列、テーブル、条件などを選択してクエリを作成できるようにする使いやすいユーザー インターフェイスを開発することになりました。最初に SQL ステートメントの抽象表現をメモリ内に作成しなくても、UI で SQL ステートメントを表現できるため、これは困難です。
最初のイテレーションは C# で作成されました。SQL ステートメントの抽象構文を表すボートロード クラスを作成しましたが、その結果、非常に扱いにくいオブジェクト モデルが作成されました。
SqlStatement インスタンスを文字列に変換することは、非常に苦痛で、見苦しく、バグが多かったです。文字列から SqlStatement への逆方向の移動は、多くの正規表現と文字列操作を使用して SQL 文字列の断片をばらばらにするため、さらに悪化しました。
私はシステムをハッキングし、機能するアプリケーションを作成しましたが、あまり満足できませんでした。アプリのビジネス要件が変更されたときは特にそうではありませんでした。そのため、C# コードを再検討する必要がありました。
実験として、F# で SqlStatement を書き直して、共用体として表現しました。
type dir = Asc | Desc
type op = Eq | Gt | Gte | Lt | Lte
type join = Inner | Left | Right
type sqlStatement =
| SelectedColumns of string list
| Joins of (string * join) list
| Wheres of (string * op * string) list
| OrderBys of (string * dir) list
type query = SelectedColumns * Joins * Wheres * OrderBys
この少量のコードは、数百行の C# と 12 ほどのクラスを置き換えました。さらに重要なことは、パターン マッチングによって、抽象表現を SQL 文字列に変換するために必要なプロセスが簡素化されたことです。
楽しい部分は、fslex/fsyacc を使用して SQL 文字列をクエリ オブジェクトに変換することでした。
私の記憶が正しければ、元の C# コードは合計 600 行、約 12 個のクラス、乱雑な正規表現がたくさんあり、作成とテストに 2 日かかりました。比較すると、F# コードは約 40 行の 1 つの .fs ファイルで構成され、レクサー/パーサーを実装するのに 100 行程度であり、テストに 1 日のうち数時間を費やしました。
真面目な話、アプリのこの部分を F# で書くのはカンニングのように感じました。
Haskell を使用して、エキゾチックなデリバティブの記述、価格設定、監視のためのドメイン固有言語を実装しました。
関数型プログラミングは、手続き型/構造化プログラミング、オブジェクト指向プログラミング、ジェネリック/テンプレート化プログラミングのようなパラダイムです。チューリング完全なので、やりたいことは何でもできます。
数学と科学は別として、パーサー コンビネーター、人工知能、同時実行性、動的評価、コルーチン、継続、簡潔な表記 (頭脳からキーボード、テキスト ファイルへのサイクルが速くなり、維持するコードが少なくなる) が容易になります。 、強く型付けされたパラメーター化 (Haskell の代数型を参照)、および動的な自己反映 (たとえば、REPL を使用した最小限のメタサーキュラー インタープリター)。
あなたのために別のものを手に入れました:
私は、小規模から中規模の銀行、地方自治体、証券取引所などを対象とした一連の新しいエンタープライズ規模の金融商品のプロトタイプ作成のごく初期の段階に携わっています。たくさんの計算をしているに違いない」 -- 実際、いいえ。これらの製品は、高度にカスタマイズ可能であり、ユーザーがアプリケーションの戦略的なポイントにビジネス ルールを挿入できるようにすることを目的としています。
ビジネス ルールを表現および解釈するために F# を使用しています。単純な例を使用して、チェック処理のコードを書いてみましょう。ルールは次のように記述します。
type condition =
| Test of string
| And of condition * condition
| Or of condition * condition
| Not of condition
type transactionWorkflow =
| Reject
| Approve
| AdministratorOverride of string
| If of condition * transactionWorkflow list
(* condition, true condition *)
| IfElse of condition * transactionWorkflow list * transactionWorkflow list
(* condition, true condition, false condition *)
| AttachForms of string list
ユーザーは、特別なアプリケーションを使用して、上記の構造で表されるいくつかのビジネス ルールを作成できます。例えば:
let checkProcessingWorkflow =
[If(Test("account doesn't exist")
,[AdministratorOverride("Account doesn't exist. Continue?");
AttachForms ["40808A - Null Account Deposit"]]
);
If(Test("deposit > 10000")
,[
If(And(Test("account created within 3 months")
,Test("out of country check"))
,[Reject]);
IfElse(Test("account state = TX")
,[AttachForms ["16A"; "16B"]]
,[AttachForms ["1018"]]
)
]
);
Approve
]
そのため、1 つのビジネス ルール エンジンを記述してすべてを制御するのではなく、特定のプロセスを F# によって解釈される非常に小さなドメイン固有の言語として処理します。このアプローチにより、競合するルールを検出する必要なく、ビジネスで読み取り可能な非常に単純な DSL を設計できるようになることを願っています。
もちろん、上記のすべては単なる概念コードであり、ルール システムの 1 つをプロトタイピングする非常に初期の段階にまだあります。Java や C# ではなく F# を使用している理由は、パターン マッチングです。
「Erlang 入門」には、必要に応じた広範なクライアント/サーバーの例 (セクション 1.3.5 から) があります。
機能的なスタイルは使えば使うほど好きになります。別の質問からのこの Python フラグメントを検討してください。
>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]
これは確かに多かれ少なかれ数学的なステートメントですが、Pythonには多くのジェネレーターがあります。慣れれば、ループの代わりにリスト内包表記を使用することは理解しやすく、バグが発生する可能性も低くなります (「1 つずれて」バグが発生することはありません)。
数値の関数型プログラミングに関する本を書いているのは私だけだと思っていたので、本当に興味深い質問です!
関数型プログラミングは、歴史的に、他のプログラムを操作するプログラムを作成することを意味するメタプログラミングにはるかに一般的に使用されてきました。これには、インタープリターとコンパイラー (DSL など) のほか、定理証明 (Coq、Isabelle) や項書き換えシステム (Mathematica などのコンピューター代数システム) などの難解なアプリケーションが含まれます。Meta Language (ML) ファミリの言語は、この目的のために特別に設計されました。
関数型プログラミングに関する多くの本が「数値プログラミング」を使って教えているのは事実ですが、例外もあります。
Haskell School of Expressionは、マルチメディアを教育手段として使用する Haskell の初心者向けの本です。
実世界の Haskellは、本全体を通して実際に特定の手段を持っているわけではありませんが、関数型スタイルで「実際の」プログラムを書くことをカバーするいくつかの章があります。
最近では、非関数型言語 (広義の意味で) で DSL レクサー/パーサーを作成することさえ考えていません。ADT とパターン マッチングにより、非常に簡単になります。
パターン マッチングは、関数型プログラミングが得意とする分野でもあり、バイオインフォマティクスなどの分野で非常に役立ちます。
しかし、今日の優れたコンパイラを考えると、関数型プログラミングはほぼあらゆる場所で活躍します。
LISP を関数型プログラミング言語と見なす人のために、common lisp で書かれた http サーバーがあり、1994 年の論文で紹介され、2006 年にまだ開発中です。
より現代的なものについては、google に「haskell web server」と尋ねてみてください。興味深い例がいくつか見つかるでしょう。http://code.haskell.org/というサイトを見つけました。
「純粋に機能的なデータ構造」を確認してください(そして、この本に影響を与えた博士論文はここにあります)。
これらは、純粋に機能的な (副作用のない) 言語で標準的なデータ構造を作成する方法を示しています。その後、それらを使用して何でもプログラムできます。
免責事項:私はここでアトウッドを引っ張っています.私は本のレビューを2、3読んだだけで、論文にざっと目を通しました.それは私のtoreadリストに載っています.
私が挙げることができる最も具体的な例は、ANTLR パーサー ジェネレーターで (他の多くの場所の中で) 使用されるテンプレート エンジンであるStringTemplateです。
StringTemplate の設計と開発に関する 1 つの論文で、Terence Parr は、もともと関数型プログラミングに懐疑的だったので、StringTemplate が本質的にテキストを生成するための関数型言語であることに気付いたとき、自分自身を大笑いしたと書いています。
アルゴリズムのギャップを埋める: Oege De Moor、Jeremy Gibbons による段落整形のための線形時間機能プログラム (1997)
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.33.7923
Koen Claessen、Ton Vullinghs、Erik Meijer による TkGofer のグラフィカル パラダイムの構造化 (1997) http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.38.5525
Gert Florijn による関数型パーサーによるオフィス プロセスのモデル化 (1994 年)
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.1307
LINQ は、関数型プログラミングから多くの手がかりを得ています。任意の LINQ プロバイダーがどのように実装されているかを調べると、実用的な洞察が得られる場合があります。