Coming from the Haskell world, where there's only a single Doc type, the amount of abstraction and polymorphism in this library feels very daunting and complicated. It would be nice to document the motivation for these adaptations. For example, what's the difference between each allocator? What do the traits such as DocAllocator and DocPtr do and how do they help abstracting over allocators?