簡體   English   中英

功能編程和類型系統

[英]Functional Programming and Type Systems

我一直在學習各種函數式語言,包括Haskell,Scala和Clojure。 Haskell有一個非常嚴格且定義良好的靜態類型系統。 Scala也是靜態類型的。 另一方面,Clojure是動態類型的。

所以我的問題是

  1. 類型系統在函數式語言中扮演什么角色?
  2. 語言是否有必要使用類型系統才能使其正常運行?
  3. 語言的“功能”級別與語言類型系統的類型有何關聯?

語言不需要輸入功能 - 函數式編程的核心是lambda演算 ,它是無類型和類型變體。

類型系統扮演兩個角色:

  • 它在編譯時提供了一種保證,即在運行時不會發生一類錯誤。 錯誤類通常包括嘗試將兩個字符串添加到一起,或嘗試將整數應用為函數。
  • 它具有一些效率優勢,因為運行時的對象不需要攜帶它們的類型,因為類型已經在編譯時建立。 這被稱為類型擦除

在像Haskell這樣的高級類型系統中,類型系統可以提供更多好處:

  • 重載:使用一個標識符來引用不同類型的操作
  • 它允許庫根據其使用的類型自動選擇優化的實現(使用Type Families
  • 它允許在編譯時證明強大的不變量,例如紅黑樹中的不變量(使用廣義代數數據類型

類型系統在函數式語言中扮演什么角色?

對於Simon Marlow的優秀答案,我想補充一個類型系統,特別是包含代數數據類型的系統 ,可以更容易地編寫程序:

  • 面向對象語言中的軟件設計有時使用UML圖表示,使用類型非常清楚地表達。 這種清晰度尤其表現在不僅具有類型,而且模塊具有類型,如在Objective Caml或Standard ML中。

  • 當一個人編寫代碼時,一些簡單的啟發式方法可以很容易地根據類型編寫純函數:

    • 始終可以使用lambda創建函數類型的值。
    • 通過應用它可以始終消耗函數類型的值。
    • 可以通過應用任何類型的構造函數來創建代數數據類型的值。
    • 通過用case表達式仔細檢查代數數據類型的值,可以消耗它。

    基於這些觀察結果,以及簡單的規則,除非有充分的理由,函數應該使用它的每個參數,否則很容易減少可以寫入極少數候選者的可能代碼的空間。 例如,沒有那么多合理的類型函數(使用Haskell表示法)

     forall a . (a -> Bool) -> [a] -> Bool 

    使用類型創建代碼的技術稱為類型導向編程。 當它運行良好時,你會聽到功能程序員說“一旦我們得到了正確的類型,代碼實際上就自己編寫了”。 由於類型通常比代碼小得多,這是一個很大的勝利。

  1. 與任何編程語言相同:它可以幫助您避免/查找代碼中的錯誤。 在靜態類型的情況下,良好類型系統可防止編譯具有某些類型錯誤的程序。
  2. 沒有。 無類型的lambda演算是你可以稱之為函數式編程語言的原型,顧名思義,它完全是無類型的。
  3. 在函數式語言(以及函數可用作值的任何其他語言)中,類型系統需要知道函數的類型。 除此之外,功能語言的類型系統沒有什么特別之處。

    在純函數式語言中,您需要抽象副作用,因此您希望類型系統能夠以某種方式支持它。 例如,如果您希望擁有類似於Clean的世界類型,則您希望類型系統支持唯一性類型以確保正確使用。

    如果你想在haskell中有一個IO monad,你需要一個IO類型(雖然像haskell這樣的monad類型類不需要有一個IO monad,所以你不需要一個支持它的類型系統) 。

1:與其他任何一個相同,它會阻止你進行不明確的操作,或者對人類造成“無意義”的操作。 就像浮點數加上整數一樣。
2:Nope是世界上最古老的編程語言,(無類型的)lambda演算,既有功能也有無類型。
3:很難,功能只是意味着沒有副作用,沒有突變,參考透明等等。

只記得最古老的函數式語言,無類型的lambda演算沒有類型系統。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM