質問
要素への高速アクセスと変更を可能にするデータ型を作成したいと考えています。単純な 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)