I'd like to know what kind of real life problems can be tackled by "duality methods" in functional programming. More precisely, I'd like to know whether someone did actually use a duality method like the ones I present below, or whether there are other interesting examples. I'd be particularly interested in existing implementations, probably in Haskell.
[Since the majority of people which will be interested in this question likely know Haskell, let me please add the Haskell tag, even if the question is quite language independent]
Let me explain what I mean by duality (by lack of a better name) through a few examples. The first one is the real numbers. Assume the existence of a Integer
and a Rational
type, and define a real number as a function (pardon my Haskell, I'm no hardcore haskeller)
type Real = Integer -> Rational
such that whenever x :: Real
denotes the real number x, x n
yields a rational number which is within 2^(-n)
of x.
Now one can do
(+) :: Real -> Real -> Real
(+) x y n = (x $ n + 1) + (y $ n + 1)
or likewise for other arithmetic operations. Given a continuous real function f, one can also compute f x
as soon as one can compute a modulus of continuity for f
.
This has the advantage that one can write natural looking code, and at the end, get a result at the desired level of precision automatically. However, it is no longer possible to compare real numbers for equality. The only kind of comparison possible between x
and y
is x < y + eps
.
Another example of duality is this question on probability measures, which triggered the present question in my head. Let us write
type Measure a = (a -> Double) -> Double
and define measures as integration procedures against functions. In the linked question, I show how natural it is in this framework to express concepts like convolution or pushforward which are much more difficult (computationally, but also theoretically) to define at the level of probability densities.
It allows one to compose building blocks from probability theory, and in principle allows one to build complex Monte Carlo procedures, and even allows one to work with explicit probability densities (at the expense of numerical integration). I'd be especially interested in any attempt at a real world library on this topic.
Another example that I have in mind, but did not quite formalize yet is the notion of vector fields (from differential geometry), that one can express as differentiation operators. For this, one needs a suitable type of "smooth real valued functions", and then a vector field is like this:
type VectorField = SmoothFunction -> SmoothFunction
such that v (f * g) = f * (v g) + g * (v f)
.
Of course, describing a sheaf of regular functions in say Haskell should not be easy. But by doing that, we could express all the stuff from differential geometry in a totally coordinate independant way, and plug coordinates at the very end.
There are other examples, eg. Taylor series have been discussed in Sigfpe's blog (I can't find this particular post though), where an analytic function is the following type:
type AnalyticFunction = Double -> Integer -> [Double]
and where f x n
returns the n
first partial sums of the Taylor expansion of f
around x
. This allows us to seamlessly write all kind of arithmetic on analytic functions, including stuff like f / g
where f
and g
both can vanish at a point (along with some of their derivatives), or even f^(-1)
(provided f'
does not vanish). At the end, only the necessary terms of the intermediate series are computed to yield the value of a given expression.