2012-12-02 38 views
8

由於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」的行爲只是被認爲是明顯的東西?

回答

8

每對報告Datatype renamings的部分,

不同於代數數據類型,所述NEWTYPE構造N被未提升,因此N個⊥是一樣的⊥。

這裏

Sum ⊥ = ⊥ 

所以NEWTYPE的弱頭正常形式是包裝類型的WHNF,和

Sum (lengthyComputation :: Int) `using` rseq 

評估lengthyComputation(當整個表達式,一個僅僅裝訂

let x = Sum (lengthyComputation :: Int) `using` rseq 

當然不會,但沒有newtype構造函數的情況是一樣的)。

defining equationsseq

seq ⊥ b = ⊥ 
seq a b = b, if a ≠ ⊥ 

因此

seq (Sum ⊥) b = ⊥ 

seq (lengthyComputaton :: Int) b 

seq需要找出(對於擬人遺憾)lengthyComputation :: Int是否是⊥或n OT。爲此,它必須評估lengthyComputation :: Int


重新更新:

newtype s爲未提升,這意味着,構造不是值構造語義(僅語法)。 newtype構造函數上的模式匹配與data構造函數上的模式匹配不太嚴格相反。鑑於

newtype Foo a = Foo { unFoo :: a } -- record syntax for convenience below 

一 「模式匹配」

function :: Foo a -> Bar 
function (Foo x) = whatever x 

完全等同於

function y = let x = unFoo y in whatever x 

比賽總是成功,並評估什麼。 The constructor only coerces the type和其上的「模式匹配」取消強制值的類型。

seq很神奇,它不能在Haskell中實現。你可以寫,做同樣的seqdata類型,像你上面的seqMaybe,在Haskell的函數,而不是一個(多態)newtype,因爲「模式匹配」的NEWTYPE構造不嚴格。你將不得不匹配包裝類型的構造函數,但對於多態newtype,你沒有它們。

+0

謝謝你的回答。但我覺得「newtype」這個步驟是嚴格的,所以它的WHNF是內部的WHNF「並不精確。我修改了這個問題,並試圖詳細表達我的疑問。 –

+2

這並不是說'newtype's嚴格的,那就是他們_unlifted_,使WHNF傳播。 –

+0

擴展答案,這個更明確嗎? –