The question
I want to create a datatype, which will allow for fast access and modification of its elements. Is it possible to create in Haskell a structure and functions, which will perform as fast as simple C++ implementation?
Problem details
I'm writing an compiler in Haskell. I've got AST represented by a datatype, let's consider following one:
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}
Each AST node has got an unique identifier. I would love to implement in Haskell following functionality:
- a function
getById
, which will return an AST node of choosen id inO(1)
time complexity. - be able to create "focuses" on the structure and modify focused elements independently from each other. So I would like to be able to remember focuses on some sub-trees and be able to modify each of such focus in
O(1)
time complexity.
I was thinking about Zippers, but there are 3 problems with them:
- They are used (as far as I know) with simple datatypes, like binary trees, where we can say, we choose "left" or "right" branch. Is there any simple way to use them on complex datatypes like the one above?
- I think they will not allow me to implement the function
getById
withO(1)
time complexity, am I right? - I think it is impossible to create some independent focuses using Zippers. By independent focuses I mean, focuses, which will allow us to modify different parts of the datatype without need of recomputing other focuses (in
O(1)
).
The C++ way of thinking
In C++ we would be able to create array of pointers to AST nodes nodePtrs
. The function nodeById
would perform in O(1)
, simply by accessing *(nodePtrs[id])
. Because the C++ structure is mutable, we would be able to modify its elements without any restrictions in O(1)
.