這是一個愚蠢的問題,一直在困擾着我。爲什麼我不能寫一個具有多個參數的新類型,多參數newtype僞造一個元組?
newtype A = A Int Int
而元組版本就好了?
newtype A = A (Int, Int)
前者在模式匹配等事情上要好得多。
這是一個愚蠢的問題,一直在困擾着我。爲什麼我不能寫一個具有多個參數的新類型,多參數newtype僞造一個元組?
newtype A = A Int Int
而元組版本就好了?
newtype A = A (Int, Int)
前者在模式匹配等事情上要好得多。
newtype A = A Int
創建一個與Int
同構的類型。就是說,它的行爲完全像Int
w.r.t.例如bottom
,但名稱不同。
這與data A = A Int
形成鮮明對比,該創建的行爲與Int的行爲不同。還有另一個值不在Int
:A undefined
(與undefined::A
不同)。
現在,newtype A = A (Int, Int)
創建一個與(Int, Int)
同構的類型。順便說一句,這正是data A = A Int Int
所做的。
所以,如果我們承認newtype A = A Int Int
等同於newtype A = A (Int, Int)
,我們有什麼? newtype A = A Int Int
相當於newtype A = A (Int, Int)
,相當於data A = A Int Int
。
newtype A = A Int Int
相當於data A = A Int Int
(所以newtype
是在這種情況下冗餘),但
newtype A = A Int
是不相當於data A = A Int
(這是在第一位置具有newtype
整點)。
所以我們必須得出結論newtype A = A Int Int
相當於newtype A = A (Int, Int)
會造成冗餘和不一致,我們最好不允許它。
有可能沒有辦法給newtype A = A Int Int
一些其他的意思是免費的,從這些不一致(否則會被發現和使用,我想;)
因爲newtype
,粗略地說,就像type
在運行時如編譯時的data
。每個data
定義增加了一個額外的間接層 - 在正常情況下,這意味着另一個不同的地方,其中某些東西可以作爲thunk保留 - 圍繞其保留的值,而newtype
則不然。 newtype
上的「構造函數」基本上只是一種幻想。
凡是將多個值成一個,或者,讓多個案件之間的選擇,必須引入了一個間接層來表達,所以newtype A = A Int Int
邏輯解釋將是兩個斷開Int
值與無「它們保持在一起」 。 newtype A = A (Int, Int)
的區別在於元組本身增加了額外的間接層。
將此與data A = A Int Int
與data A = A (Int, Int)
對比。前者在兩個Int
周圍添加一層(A
構造函數),而後者在元組周圍添加相同的圖層,該圖層本身圍繞Int
添加一層。
每一層間接還通常增加一個地方可以⊥,所以考慮每種形式的可能情況下,在哪裏?代表非底值:
對於newtype A = A (Int, Int)
:⊥
,(⊥, ?)
,(?, ⊥)
,(?, ?)
對於data A = A Int Int
:⊥
,A ⊥ ?
,A ? ⊥
,A ? ?
對於data A = A (Int, Int)
:⊥
, A ⊥
,A (⊥, ?)
,A (?, ⊥)
,A (?, ?)
從上面可以看出,前兩個是等價的。
最後要注意,這裏有究竟有多newtype
從data
不同的樂趣演示。考慮這些定義:
data D = D D deriving Show
newtype N = N N deriving Show
什麼可能的值,包括所有可能的⊥s,這些都有嗎?你認爲以下兩個值是什麼?
d = let (D x) = undefined in show x
n = let (N x) = undefined in show x
將它們加載到GHC中找出!
你讀過[this](http://www.haskell.org/haskellwiki/Newtype)嗎? –
@ n.m。,感謝您的鏈接,但您能否詳細說明實際問題?它與匹配'(A _ _)'有關嗎?我不明白爲什麼元組等價會導致不直觀的行爲。 – gatoatigrado