Я хотел бы знать, какие проблемы реальной жизни могут быть решены с помощью "методов двойственности" в функциональном программировании.Точнее, я хотел бы знать, действительно ли кто-то использовал метод двойственности, подобный представленному ниже, или есть другие интересные примеры.Я был бы особенно заинтересован в существующих реализациях , возможно, в Haskell.
[Поскольку большинство людей, которые будут интересоваться этим вопросом, вероятно, знают Haskell, позвольте мне добавитьтег Haskell, даже если вопрос не зависит от языка]
Позвольте мне объяснить, что я имею в виду под двойственностью (отсутствием лучшего названия), на нескольких примерах.Первый - это действительные числа .Предположим, что существуют типы Integer
и Rational
, и определим действительное число как функцию (простите мой Haskell, я не хардкорный haskeller)
type Real = Integer -> Rational
, такой, что всякий раз, когда x :: Real
обозначает действительное число x, x n
дает рациональное число, которое находится в пределах 2^(-n)
от x.
Теперь можно сделать
(+) :: Real -> Real -> Real
(+) x y n = (x $ n + 1) + (y $ n + 1)
или аналогично для других арифметических операций.Учитывая непрерывную вещественную функцию f, можно также вычислить f x
, как только можно вычислить модуль непрерывности для f
.
Это имеет то преимущество, что можно написать натуральноеищите код и в конце получите результат с желаемым уровнем точности автоматически.Однако больше нельзя сравнивать реальные числа на равенство.Единственное возможное сравнение между x
и y
- это x < y + eps
.
Еще один пример дуальности - этот вопрос по вероятностным мерам , который вызвалНастоящий вопрос в моей голове.Давайте напишем
type Measure a = (a -> Double) -> Double
и определим меры как процедуры интеграции с функциями.В связанном вопросе я покажу, насколько естественно в этих рамках выражать такие понятия, как свертка или толчок вперед, которые гораздо сложнее (вычислительно, но и теоретически) определить на уровне вероятности плотности .
Это позволяет составлять строительные блоки из теории вероятностей и в принципе позволяет строить сложные процедуры Монте-Карло, и даже позволяет работать с явными плотностями вероятности (за счет численного интегрирования).Я был бы особенно заинтересован в любой попытке создать реальную библиотеку по этой теме.
Еще один пример, который я имею в виду, но еще не полностью формализовал, - это понятие векторных полей (из дифференциальной геометрии), который можно выразить как операторы дифференцирования .Для этого нужен подходящий тип «гладких вещественных функций», а затем векторное поле выглядит так:
type VectorField = SmoothFunction -> SmoothFunction
такой, что v (f * g) = f * (v g) + g * (v f)
.
Конечно, описываяНапример, в Haskell не должно быть ничего сложного.Но, сделав это, мы могли бы выразить весь материал из дифференциальной геометрии полностью независимым от координат способом и вставить координаты в самом конце.
Есть и другие примеры, например. серия Тейлора обсуждалась в блоге Sigfpe (хотя я не могу найти этот конкретный пост), где аналитическая функция имеет следующий тип:
type AnalyticFunction = Double -> Integer -> [Double]
и где f x n
возвращаетn
первые частичные суммы расширения Тейлора f
вокруг x
.Это позволяет нам легко писать все виды арифметики для аналитических функций, включая такие вещи, как f / g
, где f
и g
оба могут исчезать в некоторой точке (вместе с некоторыми их производными), или даже f^(-1)
(при условииf'
не пропадает).В конце вычисляются только необходимые члены промежуточного ряда, чтобы получить значение данного выражения.