質問
要素への高速アクセスと変更を可能にするデータ型を作成したいと考えています。単純な C++ 実装と同じくらい高速に実行される構造体と関数を Haskell で作成することは可能ですか?
問題の詳細
私はHaskellでコンパイラを書いています。データ型で表されるASTを取得しました。次の 1 つを考えてみましょう。
import Prelude hiding (id)
-- this is a sample data type, the real one has got a lot of constructors
data AST = A { id :: Int, x :: AST, y :: AST, z :: AST }
| B { id :: Int }
| C { id :: Int, x :: AST, y :: AST }
| D { id :: Int, u :: AST, v :: AST, w :: AST}
各 AST ノードには一意の識別子があります。Haskell で次の機能を実装したいと思います。
- 選択された ID の時間計算量
getByIdの AST ノードを返すfunction 。O(1) - 構造に「フォーカス」を作成し、フォーカスされた要素を互いに独立して変更できます。したがって、いくつかのサブツリーに焦点を当て、そのような焦点のそれぞれを
O(1)時間の複雑さで変更できるようにしたいと考えています。
Zippersについて考えていましたが、3 つの問題があります。
- それらは (私が知る限り) 二分木などの単純なデータ型で使用され、「左」または「右」ブランチを選択すると言えます。上記のような複雑なデータ型でそれらを使用する簡単な方法はありますか?
- 時間の複雑さで関数
getByIdを実装することはできないと思いますよね?O(1) - Zippers を使用していくつかの独立したフォーカスを作成することは不可能だと思います。独立したフォーカスとは、フォーカスを意味します。これにより、他のフォーカスを再計算する必要なく、データ型のさまざまな部分を変更できます (
O(1))。
C++ の考え方
C++ では、AST ノードへのポインタの配列を作成できますnodePtrs。にアクセスするだけで、関数nodeByIdは で実行されます。C++ 構造は変更可能であるため、.O(1)*(nodePtrs[id])O(1)