由於newtype
在編譯過程中被有效移除,所以它們沒有thunk,只是值。那麼如果我使用rseq
來詢問其WHNF會發生什麼?例如,在新類型的WHNF是什麼?rseq如何處理新類型?
Sum (lengthyComputation :: Int) `using` rseq
其中Sum
定義爲
newtype Sum a = Sum { getSum :: a }
將lengthyComputation
得到評估或不?是否在某處指定/記錄,以便我可以依靠它?
更新:讓我解釋一下我的懷疑更多的細節。直覺地說:「newtype
是嚴格的如此清楚它的WHNF是什麼被包裹的WHNF」。但我覺得這是一條非常不準確的捷徑,推理不太清楚。我舉一個例子:
對於標準的data
類型,WHNF可以定義爲一個表單,我們知道哪個構造函數用於構造該值。如果,例如,我們沒有seq
,我們可以創造我們自己的
seqMaybe :: Maybe a -> b -> b
seqMaybe Nothing = id
seqMaybe _ = id
同樣地,對於任何data
類型,只是圖案的構造函數之一匹配。
現在,讓我們
newtype Identity a = Identity { runIdentity :: a }
,並創建一個類似seqIdentity
功能:
seqIdentity :: Identity a -> b -> b
seqIdentity (Identity _) = id
清楚,沒有被強迫在這裏WHNF。 (畢竟,我們總是知道使用了什麼構造函數。)編譯之後,seqIdentity
將與const id
相同。實際上,創建多態的seqIdentity
是不可能的,因此它將強制評估Identity
中的值!我們可以將的WHNF a定義爲未修改的值,並且它是一致的。所以我相信問題是,WHNF是如何爲newtype
定義的?還是沒有嚴格的定義,而「這是什麼內在的WHNF」的行爲只是被認爲是明顯的東西?
謝謝你的回答。但我覺得「newtype」這個步驟是嚴格的,所以它的WHNF是內部的WHNF「並不精確。我修改了這個問題,並試圖詳細表達我的疑問。 –
這並不是說'newtype's嚴格的,那就是他們_unlifted_,使WHNF傳播。 –
擴展答案,這個更明確嗎? –