質問

Python では、map() はシーケンス プロトコルに従うあらゆるデータに対して機能します。文字列、リスト、さらにはタプルを与えても、それは正しいことを行います^TM。

OCaml でケーキも作ることはできないでしょうか?本当に、使用しているコレクション型を調べて、対応する List.map または Array.map または Buffer.map または String.map を見つける以外に選択肢はないのでしょうか?中には存在すらしないものもあるのです!私が求めているものは普通ではないのでしょうか?何かが足りないに違いない。

役に立ちましたか?

解決

これに最も近いのは、モジュール OCamlバッテリーが含まれています Enum a>(以前は Extlib の)。 Enum は、マップと Enum.t の折り畳みを定義します。データ型に Enum.t との間の変換を使用する必要があります。 Enum.t は遅延しているため、変換はかなり軽量です。

本当に欲しいのはHaskellスタイルの型クラス、たとえば Foldable および Functor (" maps"を一般化します)。 Haskellライブラリは、リスト、配列、およびツリーの Foldable および Functor のインスタンスを定義します。別の関連するテクニックは、"ボイラープレートを廃棄する"です。汎用プログラミングへのアプローチ。 OCamlは型クラスまたは高次のポリモーフィズムをサポートしていないため、このようなパターンを型システムで表現できるようになります。

他のヒント

OCaml には 2 つの主なソリューションがあります。

  1. Jacques Garrigue は、数年前に構文的には軽いが非効率なアプローチを多くのデータ構造に対してすでに実装しています。コレクションをオブジェクトでラップするだけで、 map 方法。そうすれば、次のことができます collection#map あらゆる種類のコレクションにマップ関数を使用します。これは、さまざまな種類のデータ構造を置き換えることができるため、要件よりも一般的です。 実行時. 。ただし、これは実際にはあまり役に立たないため、このアプローチは広く採用されることはありませんでした。

  2. 構文的には重くなりますが、効率的で堅牢かつ静的な解決策は、ファンクターを使用して、使用しているデータ構造に対してコードをパラメーター化することです。これにより、異なるデータ構造でコードを再利用することが簡単になります。いくつかの優れた例については、岡崎氏の著書「Purely Functional Data Structures」の Markus Mottl 氏による OCaml 翻訳を参照してください。

そのような機能を求めておらず、単に簡潔にしたい場合は、もちろん、短い名前のモジュール エイリアスを作成することもできます (例:モジュール S = 文字列)。

問題は、各コンテナの表現が異なり、map / reduceを反復処理するために異なるコードが必要なことです。これが、別個の機能がある理由です。ほとんどの言語は、コンテナ用のある種の一般的なインターフェイス(前述のシーケンスプロトコルなど)を提供するため、map / reduceなどの機能を抽象的に実装できますが、これは、言及したタイプに対しては行われません。

モジュールでtype tとval compare(:t-> t-> int)を定義している限り、Map.Makeは必要なマップを提供します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top