math - world - windows haskell



函數式編程中的對偶性方法 (1)

您的示例的共同特徵是按函數表示某些(數學)對象。 這在函數式語言中很常見,但不像數學那樣實用,因為程序中的函數是擴展使用的(你不能檢查它們的定義,只能觀察它們對參數的作用),並且只能用可計算的操作(你只能觀察有限數量的參數)。

在數學中,你不必費心這些東西,例如你經常說“如果f是解析,那麼讓(a_n)成為它的係數序列,並且......”。 在計算機語言中,如果您使用Double -> Integer -> [Double]類型的函數開始,將它轉換為可以輕鬆恢復係數的表示將會很痛苦。 在編程語言中,功能確實是黑盒子。

出於這個原因,程序員經常嘗試使用顯式數據表示而不是功能黑盒子。 您可以輕鬆地從數據表示中獲取函數(它是一種評估或解釋),而另一種方式可能更難,效率更低等。請參閱Conal Elliott 在Haskell中“Everything is a function”?

但是,在我們真正需要拉伸對象的情況下仍然使用函數,這些對像只能被觀察而不是被檢查。 對於要定義的對象的每個可能的觀察,您將提供實現此觀察的功能。 在您的示例中,您只有一個函數,因為您只有一個觀察。 這是William Cook在他的On Understanding Data Abstraction,Revisited論文中定義的面向對象編程的核心思想。

我認為你之所以把它與術語“二元性”(在Haskell知識分子中,與類別理論概念相關的術語)聯繫起來的原因在於,從一個對像到某種特定形式的觀察的轉變有時是在數學中稱為二元性,並且具有在任何地方添加函數的效果。 例如,有一個向量空間對偶的經典例子,特別是雙向構造,它實際上是從向量到線性函數觀察的轉換:你從V切換到(V -> K) -> K ,對於K向量空間下面的字段。

(人們會想到延續閱讀我的最後一個例子嗎?當然這些是相關的,因為這種延續的表示實際上是對具體評價背景的“觀察”,以他們對價值觀的行為來表示。)

您對概率度量的表示實際上用於定義函數式語言中的概率度量單子。 有不同的方法來定義概率單子。 參見例如Norman Ramsey和Avi Pfeffer的http://www.cs.tufts.edu/~nr/pubs/pmonad-abstract.html 。 然而,概率DSL的大多數現實世界實現使用更具體的表示,例如[(prob,event)]對的列表(Haskell probability庫和OCaml okmij.org/ftp/kakuritu )。

最後,有關將實數表示為函數的示例,請參閱Russel O'Connor的A Monadic,Real Numbers of Real Numbers 。 存在許多“可計算”數字的表示並且具有不同的優點,並且它們中的大多數基於序列並且因此可以表示為Integer -> ...函數。

我想知道函數式編程中“對偶方法”可以解決什麼樣的現實問題。 更準確地說,我想知道是否有人確實使用了我下面提到的二元方法,或者是否有其他有趣的例子。 我對可能在Haskell中的現有實現特別感興趣。

[由於大多數對此問題感興趣的人可能都知道Haskell,請允許我添加Haskell標記,即使問題與語言無關]

讓我通過幾個例子來解釋我的意思是二元性(缺乏一個更好的名字)。 第一個是實數 。 假設存在一個Integer和一個Rational類型,並將一個實數定義為一個函數(原諒我的Haskell,我不是硬核的haskeller)

type Real = Integer -> Rational

這樣,只要x :: Real表示實數x, xn產生一個有理數,它在x的2^(-n)範圍內。

現在可以做到

(+) :: Real -> Real -> Real
(+) x y n = (x $ n + 1) + (y $ n + 1)

或類似地用於其他算術運算。 給定連續的實函數f,一旦可以計算f 的連續模數,也可以計算fx

這樣做的好處是可以編寫自然的代碼,最後自動獲得所需的精度。 但是,不再可能比較實數是否相等。 xy之間唯一可能的比較是x < y + eps

另一個二元性的例子就是關於概率測量的這個問題 ,它引發了我腦海中的現有問題。 我們來寫吧

type Measure a = (a -> Double) -> Double

並將度量定義為針對功能的集成過程。 在鏈接的問題中,我展示了在這個框架中表達卷積或前推等概念的自然程度,這些概念在概率密度水平上定義要困難得多(在計算上,但在理論上也是如此)。

它允許人們從概率論中構建構建塊,原則上允許人們構建複雜的蒙特卡羅程序,甚至允許人們使用顯式概率密度(以數值積分為代價)。 我對這個主題的真實世界圖書館的任何嘗試都特別感興趣。

我想到的另一個例子,但尚未完全形式化的是矢量場 (來自微分幾何)的概念,可以表示為微分算子 。 為此,需要一個合適類型的“平滑實值函數”,然後一個向量字段是這樣的:

type VectorField = SmoothFunction -> SmoothFunction

使得v (f * g) = f * (vg) + g * (vf)

當然,在Haskell中描述一堆常規函數應該不容易。 但通過這樣做,我們可以以完全獨立於坐標的方式表達來自微分幾何的所有東西,並在最後插入坐標。

還有其他例子,例如。 泰勒系列已在Sigfpe的博客中討論過(我找不到這篇特別的帖子),其中分析函數是以下類型:

type AnalyticFunction = Double -> Integer -> [Double]

並且其中fxn返回圍繞xf的泰勒展開的n第一部分和。 這允許我們在分析函數上無縫地編寫所有類型的算術,包括f / g類的東西,其中fg都可以在某一點消失(連同它們的一些衍生物),甚至f^(-1) (提供f'不會消失)。 最後,僅計算中間序列的必要項以產生給定表達式的值。





functional-programming