For reverse mode AD we use System.Mem.StableName.StableName to recover sharing information from
the tape to avoid combinatorial explosion, and thus run asymptotically faster
than it could without such sharing information, but the use of side-effects
contained herein is benign.

The gradF' function calculates both the result and the Jacobian of a nonscalar-to-nonscalar function, using m invocations of reverse AD,
where m is the output dimensionality. Applying fmap snd to the result will recover the result of gradF

gradWithF g f' calculates both the result and the Jacobian of a nonscalar-to-nonscalar function f, using m invocations of reverse AD,
where m is the output dimensionality. Applying fmap snd to the result will recover the result of gradWithF

Instead of returning the Jacobian matrix, the elements of the matrix are combined with the input using the g.

jacobian' == gradWithF' (\_ dx -> dx)

Exposed Types

AD serves as a common wrapper for different Mode instances, exposing a traditional
numerical tower. Universal quantification is used to limit the actions in user code to
machinery that will return the same answers under all AD modes, allowing us to use modes
interchangeably as both the type level "brand" and dictionary, providing a common API.