 /// An `AnyArrayBuffer` dispatcher that provides algorithm implementations for `Factor`
 /// elements.
 class FactorArrayDispatch {
+  /// The notional `Self` type of the methods in the dispatch table
+  typealias Self_ = AnyArrayBuffer<AnyObject>
+  
   /// A function returning the errors, at `x`, of the factors in `storage`.
   ///
   /// - Requires: `storage` is the address of an `ArrayStorage` whose `Element` has a
   ///   subclass-specific `VectorFactor` type.
-  final let errors: (_ storage: UnsafeRawPointer, _ x: VariableAssignments) -> [Double]
+  final let errors: (_ self_: Self_, _ x: VariableAssignments) -> [Double]
 
   /// Creates an instance for elements of type `Element`.
-  init<Element: Factor>(_: Type<Element>) {
-    let storageType = Type<ArrayStorage<Element>>()
-    errors = { storage, x in storage[as: storageType].errors(at: x) }
+  init<Element: Factor>(_ e: Type<Element>) {
+    errors = {
+      self_, x in self_[unsafelyAssumingElementType: e].storage.errors(at: x)
+    }
   }
 }
 

extension AnyArrayBuffer where Dispatch: FactorArrayDispatch {
  /// Returns the errors, at `x`, of the factors.
  func errors(at x: VariableAssignments) -> [Double] {
    withUnsafePointer(to: storage) { dispatch.errors($0, x) }
  }
}


extension AnyArrayBuffer where Dispatch: VectorFactorArrayDispatch {
  /// Returns the error vectors, at `x`, of the factors.
  func errorVectors(at x: VariableAssignments) -> AnyVectorArrayBuffer {
    dispatch.errorVectors(.init(self), x)
  }

  /// Returns the linearizations, at `x`, of the factors.
  func linearized(at x: VariableAssignments) -> AnyGaussianFactorArrayBuffer {
    dispatch.linearized(.init(self), x)
  }
}

