我是Haskell的新手,目前正在通過Real World Haskell。本書說類型構造函數僅用於類型簽名,而值構造函數用於實際代碼中。它也給出了一個聲明的例子,表明兩者的名稱是相互獨立的。爲什麼首先需要兩個構造函數,如果其中只有一個用於實際代碼?由於我們不會在實際代碼中使用類型構造函數,因此類型構造函數的用途是什麼?爲什麼除了Haskell中的類型構造函數外,還有一個值構造函數?
回答
也許名字有點誤導。 A 類型構造函數表示您聲明的類型的名稱。它們就是這樣調用的,因爲它們構建的是類型,而不是值:實際上,(可能)對類型變量進行參數化,它們定義了一系列類型。它們的行爲類似於C++的模板和Java的泛型。在data MyType a b = Constr a b
中,MyType是一個類型構造函數,它需要兩種類型a
和b
來構建一個新類型(MyType a b)
。
A 值構造函數是您在其他(面向對象)語言中稱爲「構造函數」的唯一部分,因爲您需要它來構建該類型的值。因此,在前面的示例中,如果採用值構造函數Constr :: a -> b -> MyType a b
,則可以創建值Constr "abc" 'd' :: MyType [Char] Char
。
請問如何改進我的答案擺脫那-1?怎麼了? – 2012-04-20 13:42:09
一種方便的方式來獲取有關類型和值的直覺是,前者是編譯時值,而後者則是運行時值。換句話說,Type構造函數是Haskell類型集合中值的構造方法,唯一目的是在編譯時鍵入您的程序。這也意味着你不能在運行時構造一個類型,並且你不能在編譯時構造一個值。所以,因爲你不能在運行時根據類型值顯式地分支(儘管你可以隱式地使用類型類型),所以類型構造函數作爲運行時對象是完全沒用的,並且在很多情況下完全沒有最終的二進制。相反,因爲值構造函數允許在運行時在它們的類型集合中構造值,所以它們作爲編譯時對象完全沒有用處。
由於這個簡單的屬性,Type構造函數和Value構造函數可以毫不含糊地共享名稱。
這是對來自緊急背景的人的最簡單理解! – 2013-06-17 13:36:52
這有點像說「爲什麼我們需要類和對象,如果對象是唯一實際運行?」
這兩種構造函數做不同的工作。類型構造函數進入類型簽名。值構造函數進入可運行代碼。
在最簡單的情況下,類型「構造函數」是只是一個類型名稱。在最簡單的情況下,一個類型只有一個值構造函數。所以,你的東西落得像
data Point = Point Int Int
你可以對自己說:「現在爲什麼赫克我需要寫Point
兩次?」
但現在考慮不那麼簡單的例子:
data Tree x = Leaf x | Branch (Tree x) (Tree x)
這裏Tree
是一個類型構造。你給它一個類型參數,它「構造」一個類型。因此Tree Int
是一種類型,Tree String
是另一種類型,依此類推。 (類似於C++中的模板,或Java或Eiffel中的泛型)。
另一方面,Leaf
是一個值構造函數。給定一個值後,它會生成一個單節點樹。所以Leaf 5
是一個Tree Int
值,Leaf "banana"
是一個Tree String
值,依此類推。
類似地對於Branch
。它需要兩個樹值並構建一個樹狀節點,並將這些樹作爲子節點。例如,Branch (Leaf 2) (Leaf 7)
是Tree Int
的值。
感謝您的詳細解釋! – 2012-04-23 06:28:13
- 1. Haskell函數構造
- 2. 子類構造函數 - 爲什麼必須爲子類構造函數存在默認構造函數?
- 3. 函數構造函數和原型構造函數有什麼區別?
- 4. 我可以在外部構造函數中爲參數類型構建一個無參數構造函數嗎?
- 5. 什麼類型是構造函數?
- 6. 爲什麼要將原型的構造函數設置爲其構造函數?
- 7. 如何在構造函數外訪問構造函數的值
- 8. 什麼類型的java構造函數是這些?構造函數鏈接?
- 9. 瞭解F#類型的構造函數
- 10. 爲什麼沒有其他構造函數,除了.edmx中的默認構造函數?
- 11. 爲什麼具有繼承構造函數的類還會獲得合成的默認構造函數?
- 12. 有一個子類的構造函數
- 13. 一類的構造函數
- 14. C#&CLI與值類型和構造函數有什麼區別?
- 15. 在Kotlin中有兩個不同構造函數的數據類構造函數
- 16. 第一類函數的函數構造
- 17. 類構造函數
- 18. 什麼是類型和什麼是類型構造函數scala
- 19. typecript中的類構造函數類型?
- 20. 是否有可能將構造函數放在另一個構造函數的構造函數中?
- 21. 空的構造函數和沒有構造函數有什麼區別
- 22. 構造函數中的調用基構造函數和其他構造函數
- 23. 爲什麼下面的類型構造函數比數據構造函數的參數少?
- 24. 沒有參數的構造函數或參數構造函數
- 25. 爲什麼這個類有兩個構造函數?
- 26. 爲什麼DomainService構造函數重載顯示爲DomainContext構造函數重載?
- 27. 從另一個構造函數調用默認構造函數
- 28. JsonSerializationException類型與私有構造函數
- 29. 爲什麼默認構造函數在父類中是必需的,如果它具有參數構造函數?
- 30. AS3函數內部構造函數與函數外部構造函數
短語「實際代碼」是不幸的,因爲它暗示你不會在程序中使用類型構造函數,而作者實際上是指類型構造函數僅用於類型註釋。這相當於說你在C中不需要關鍵字「int」或「long」,因爲你在實際代碼中不使用它們(它們只用於聲明中,它不被視爲「實際代碼「按此標準)。 – 2012-04-20 10:24:30
...不接受? :) – 2012-11-27 14:26:32