2012-12-02 18 views
8

Od newtype s są skutecznie usuwane podczas kompilacji, nie mają błędów, tylko wartości. Co się stanie, jeśli poprosię o WHNF przy użyciu numeru rseq? Na przykład wCo to jest WHNF nowego typu i jak działa rseq na nowym typie?

Sum (lengthyComputation :: Int) `using` rseq 

gdzie Sum jest zdefiniowany jako

newtype Sum a = Sum { getSum :: a } 

będzie lengthyComputation się ocenić, czy nie? Czy jest gdzieś określony/udokumentowany, żebym mógł na to liczyć?


Aktualizacja: Pozwól mi wyjaśnić moje wątpliwości w sposób bardziej szczegółowy. Intuicyjnie mówi się: "newtype jest ścisły, więc wyraźnie jego WHNF jest WHNF tego, co jest w środku". Ale uważam, że jest to bardzo nieprecyzyjny skrót, a rozumowanie nie jest tak jasne. Pozwolę sobie podać przykład:

Dla typów standardowych data, WHNF można zdefiniować jako formularz, w którym wiemy, który konstruktor został użyty do skonstruowania wartości. Jeśli, na przykład, nie mamy seq, możemy tworzyć własne

seqMaybe :: Maybe a -> b -> b 
seqMaybe Nothing = id 
seqMaybe _  = id 

i podobnie dla każdej data typu, po prostu wzór pasujący na jednym z jego konstruktorów.

Teraz rzućmy

newtype Identity a = Identity { runIdentity :: a } 

i stworzyć podobną seqIdentity funkcję:

seqIdentity :: Identity a -> b -> b 
seqIdentity (Identity _) = id 

wyraźnie, nic nie jest zmuszony do WHNF tutaj. (W końcu zawsze wiemy, jaki konstruktor był używany.) Po kompilacji seqIdentity będzie identyczny z const id. W rzeczywistości nie można utworzyć polimorficznego seqIdentity w taki sposób, że wymusi on ocenę wartości zawiniętej wewnątrz Identity! Możemy zdefiniować WHNF a z newtype jako po prostu wartość niezmodyfikowaną i byłaby spójna. Sądzę, że pytanie brzmi: jak zdefiniowano WHNF dla newtype s? Czy też nie ma rygorystycznej definicji, a zachowanie "to WHNF tego, co jest w środku" jest po prostu zakładane jako coś oczywistego?

Odpowiedz

8

Per części dotyczącej Datatype renamings w raporcie,

przeciwieństwie do typów danych algebraicznych, konstruktor newtype N unlifted, tak że N ⊥ jest taka sama jak ⊥.

Tutaj

Sum ⊥ = ⊥ 

tak słabych głowica normalnie postać newtype jest WHNF zawiniętego typu i

Sum (lengthyComputation :: Int) `using` rseq 

ocenia lengthyComputation (gdy wyrażenie jest poddane ocenie, zwykłe wiązanie

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

oczywiście nie, ale to jest to samo bez konstruktora newtypu).

defining equations dla seq

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

i stąd

seq (Sum ⊥) b = ⊥ 

aw

seq (lengthyComputaton :: Int) b 

na seq jest wymagane, aby dowiedzieć się (przepraszam za antropomorfizmu) czy lengthyComputation :: Int jest ⊥ lub n ot. Aby to zrobić, musi ocenić lengthyComputation :: Int.


Re zmiana:

newtype S są unlifted, co oznacza, że ​​konstruktor jest konstruktor wartość semantycznie (tylko składni). Dopasowywanie wzorców w konstruktorze newtype w przeciwieństwie do dopasowywania wzorca na konstruktorze data nie jest ścisłe. Biorąc

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

jest "wzór mecz"

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

jest całkowicie równoważna

function y = let x = unFoo y in whatever x 

Mecz zawsze się powiedzie, i ocenia nic. The constructor only coerces the type i "dopasowywanie do wzorca" na nim eliminuje typ wartości.

seq jest magiczne, nie można go zaimplementować w Haskell. Możesz napisać funkcję, która działa tak samo, jak seq dla typu data, np. seqMaybe powyżej, w Haskell, ale nie dla (polimorficznego) newtype, ponieważ "dopasowywanie wzorców" w konstruktorze newtype nie jest ścisłe. Musiałbyś dopasować konstruktory zawijanego typu, ale dla polimorficznego newtype, nie masz ich.

+0

Dziękuję za odpowiedź. Ale czuję, że krok "' newtype' jest ścisły, więc WHNF jest WHNF tego, co jest w środku "nie jest precyzyjny. Zmieniłem pytanie i starałem się wyrazić moje wątpliwości w szczegółach. –

+2

Nie jest tak, że 'newtype's są surowe, to dlatego, że są one unieruchomione, co powoduje propagację WHNF. –

+0

Rozszerzona odpowiedź, czy to bardziej wyjaśnia? –