任何人都可以向我解釋數據/類型構造函數和函數之間有什麼區別? Haskell將它們混合並給我們提供了一個通用界面(全部看起來像函數,特別是我們可以部分應用它們),而ML族語言區分它們。數據/類型構造函數和函數之間的區別?
回答
你的二分法「Haskell vs. ML world」是錯誤的¹。 SML也促進了構造函數的功能,並且Caml Light曾經使用過。我不確定它爲什麼在OCaml中被刪除,我認爲設計者認爲它沒有真正的需要。
構造函數爲什麼稍微有些有深刻的原因。它們可以用於模式,而一般功能則不能 - 我想這可以用極化邏輯和聚焦來解釋。另外,應用於值的構造函數可以被認爲是一個值,而對於一般函數來說則不然。在按值調用的語言中,通常將遞歸值定義限制爲允許構造函數應用程序的子類,但不允許使用通用函數應用程序。
我同意將所有構造函數提升爲函數的「語義糖」很好。不過我認爲,如果我們有一個很好的語法糖來進行短期抽象,比如斯卡拉的Some(_)
,那麼這將不會很有用。 在我看來,構造函數是否應該是curryfied(你的「部分應用」評論)是一個不同的正交問題。
¹:除了是一個錯誤的二分法,你的問題的口氣有一定的味道「Haskellers和MLers,這裏是戒指,請打!」。它可能不是有意的,但無論如何你應該避免這樣的表述。語言設計是作出妥協,並假設當兩種不同的語言做出不同的選擇時,其中一種是正確的而不是另一種不是好的方法。
PS:此問題已被編輯,現在更加中性。感謝您的編輯。
²:由petebu的要求,這裏是一個多一點(其實很多更多)的 「聚焦和極性」 的信息。我想指出,我真的不是這個話題的專家(因此我猜「)。
我會首先推薦Neelakantan Krishnaswami在2009年發佈的論文Focusing on Pattern Matching (PDF)。它包含一個不精通邏輯和聚焦(但至少需要熟悉後續微積分)的人的介紹。像往常一樣,在連續微積分中,類型/命題被引入「在右邊」並且在左邊被消除/解構。但是在這裏,我們用「極性」來分類類型,產品和總和是積極的並且功能是負的(我的直覺是產品/和數是數據,而函數是計算的,但是分離的動機來自對它們在連續微積分中行爲的非常自然的考慮)並且論文顯示左箭頭類型的消除對應於函數應用,而和/產品類型的左消除對應於模式匹配。有一個case
構造的行爲與模式匹配類似(有一些差異),消除了積極因素,所以不能應用於函數。
Dan Licata,Noam Zeilberger和Robert Harper,2008年另一重要參考文獻是Focusing on Binding and Computation(請注意,如果您打算提交關於這些主題的論文,「關注......」正在變得有點陳詞濫調)。它更少強調與ML風格模式匹配的聯繫,但引入了一個非常好的想法,即雖然計算箭頭在左邊是「負值」(很容易看作經典等值A→B ≡ ¬A∨B
),但可以引入一個不同的箭頭,「正面的左「,因此是正極化的,可以是模式匹配的。事實證明,這個箭頭非常適合表示變量綁定(如果您熟悉高階抽象語法,則認爲左邊的極性排除了試圖在變量上計算的「異國情調術語」),這樣具有變量綁定的術語是可以像樣式或產品那樣進行模式匹配的數據結構。
我發現他們的紙有點難以閱讀,所以我會從Dan Licata's slides開始。最後,羅伯特哈珀提出了other slides,提供了歸納判斷/推導的不同直覺:正向箭頭表示可衍生性(你可以在假設A和B?下建立C的推導),而負向箭頭代表可接受性 (假設A和B的派生,你將如何重寫/探索/操縱它們來構建C的派生?)。非常有趣的東西。
Haskell確實減少和簡化了一些OCaml語法。但是Haskell語法確實可以區分構造函數和函數。函數以小寫字母開頭,構造函數以大寫字母開頭。使用中綴運算符數據構造函數必須以冒號開頭,而普通運算符可能永遠不會以冒號開頭。
構造函數的接口可以看起來像簡單的(也許是部分的)函數應用程序,這使得一個參數構造函數和大多數新類型非常易於使用(只是「你好」)。但Haskell確實允許使用OCaml類記錄名稱和{field = value,field = value}樣式,但在Haskell中,您不必強制使用字段名稱或強制使用此語法。因此,OCaml只爲單個字段提供簡單的語法,但Haskell允許您爲多個字段使用簡單的語法。最終,避免字段名稱對於大型類型是不利的,因爲類似位置函數的語法很難重構。
首先必須解釋值和類型之間的差異。 「因爲Haskell是純粹的函數式語言,所有計算都是通過評估表達式(語法術語)來產生值(我們認爲是答案的抽象實體),每個值都有一個關聯的類型。 - Haskell 98的溫和介紹(本教程不太溫和)
Haskell的值是「first-class」,而Haskell的類型不是。類型用於描述值,而值和類型的關聯稱爲鍵入。
數據/類型構造函數的區別在於:應用數據構造函數會產生一個值,但應用類型構造函數會產生一個類型。
函數只是描述值的表達式,它與一個類型相關聯。當您評估函數時,您只是評估描述這些值的表達式。
- 1. 構造函數和零參數構造函數之間的區別(Java)
- 2. javascript構造函數之間的區別
- 3. Doc數據值構造函數Char和Text之間的區別
- 4. 函數和構造函數的區別
- 5. 函數構造函數和原型構造函數有什麼區別?
- 6. 構造函數和new/malloc之間的區別,析構函數與delete/free之間的區別
- 7. TypeScript:函數類型之間的區別
- 8. 構造函數和默認構造函數的區別
- 9. 抽象類構造函數和普通類構造函數的區別?
- 10. 正常的構造函數和mutator之間的區別? Java
- 11. JavaScript中的函數和構造函數之間有什麼區別?
- 12. 析構函數和函數之間的區別是什麼?
- 13. 構造函數和方法之間的區別
- 14. LoadControl和暴露構造函數之間的區別?
- 15. 默認(用戶定義的)構造函數和構造函數與默認參數之間的區別?
- 16. 單元的類型構造函數和返回函數之間的區別(在Haskell中)
- 17. Android構造函數和onCreate()之間有什麼區別?
- 18. 默認構造函數和無參數構造函數的區別?
- 19. C#&CLI與值類型和構造函數有什麼區別?
- 20. 原型對象和構造函數上的成員之間有什麼區別?
- 21. 靜態構造函數和私有構造函數之間的主要區別是什麼?
- 22. Haskell中的類型構造函數和java泛型類型有什麼區別?
- 23. =沒有參數的默認和空構造函數之間的區別?
- 24. 這些構造函數調用語句之間的區別?
- 25. 函數和函數指針之間的區別作爲參數
- 26. 空的構造函數和沒有構造函數有什麼區別
- 27. read.table和read.delim函數之間的區別
- 28. 函數和過程之間的區別?
- 29. 語句和函數之間的區別
- 30. MPI_Allgather和MPI_Alltoall函數之間的區別?
Haskell確實*不*具有「一切都是功能」的座右銘! http://conal.net/blog/posts/everything-is-a-function-in-haskell/ – sclv 2011-03-18 15:39:23