Haskell'de "data" ve "newtype" arasındaki fark


191

Bunu yazdığımda fark nedir?

data Book = Book Int Int

karşı

newtype Book = Book (Int, Int) -- "Book Int Int" is syntactically invalid

Biraz arama yapmalısınız, bu soru zaten cevaplandı. stackoverflow.com/questions/2649305/…
tehman


Ayrıca ilgili: newtype için kullanımlar: stackoverflow.com/questions/991467/…
Don Stewart

25
Bunun newtype Book = Book Int Intgeçerli olmadığını unutmayın . Ancak, newtype Book = Book (Int, Int)aşağıdaki dons ile belirtildiği gibi olabilir.
Edward KMETT

Yanıtlar:


241

Harika bir soru!

Birkaç temel fark vardır.

temsil

  • Bir newtypeverilerinizin sarın o türü olarak, zamanında tam olarak aynı gösterimi olacak garanti eder.
  • Süre dataçalışma sırasında yepyeni bir veri yapısı ilan ederken .

Buradaki anahtar nokta newtype, derlemenin yapısının derleme zamanında silineceği garantisidir.

Örnekler:

  • data Book = Book Int Int

veri

  • newtype Book = Book (Int, Int)

yeni tip

Yapıcı silindiğinden (Int,Int), a ile tam olarak aynı temsile nasıl sahip olduğuna dikkat edin Book.

  • data Book = Book (Int, Int)

veri grubu

'De Bookbulunmayan ek bir kurucu var newtype.

  • data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int

resim açıklamasını buraya girin

İşaretçi yok! İki Intalan, Bookyapıcıdaki kutulanmamış sözcük boyutlu alanlardır .

Cebirsel veri türleri

Bu yapıcıyı silmek gerektiğinden, newtypeyalnızca bir veri türünü tek bir kurucu ile sararken çalışır . "Cebirsel" yeni tipler hakkında hiçbir fikir yoktur. Yani, yeni bir tür eşdeğer yazamazsınız, örneğin,

data Maybe a = Nothing
             | Just a

çünkü birden fazla kurucusu var. Ne yazamazsın

newtype Book = Book Int Int

katılık

Yapıcı arasındaki katılığından bazı çok ince farklılıklara yol silinir gerçeği datave newtype. Özellikle, data"kaldırılmış", yani temelde bir alt değeri değerlendirmek için ek bir yolu olduğu anlamına gelen bir tür sunar. Çalışma zamanında ek kurucu bulunmadığından newtype, bu özellik tutulmaz.

İçinde O ekstra işaretçi Bookiçin (,)yapıcı bize bir alt değer koymak için izin verir.

Sonuç olarak, newtypeve datagibi biraz farklı katılık özelliklerine sahip Haskell wiki makalesinde açıklanmıştır .

Unboxing

Bir newtypekurucu olmadığı için a'nın bileşenlerinin kutularını açmak mantıklı değil . Yazmak kesinlikle makul olsa da:

data T = T {-# UNPACK #-}!Int

bir Tkurucu ve bir Int#bileşen ile bir çalışma zamanı nesnesi verir . Sen sadece bir çıplak olsun Intile newtype.


Kaynaklar :


2
Haskell'de "newtype" olmasa bile bir şeyleri özleyeceğimi hala düşünmüyorum. İnce farklılıklar benim için değerli görünmeyen bir dile karmaşıklık katıyor ...
değerli

14
Fark, performans nedeniyle çok faydalıdır. Newtype kurucuları derleme zamanında silindiği için, bir veri kurucusunun yaptığı çalışma zamanı performans cezasını dayatmazlar. Ama yine de size tamamen farklı bir türün ve onunla ilişkilendirmek istediğiniz soyutlamaların tüm avantajlarını veriyorlar. Örneğin, liste veri türünün bir monad oluşturması için iki farklı yol vardır. Biri dilde yerleşiktir, ancak diğerini kullanmak isterseniz, yeni bir yöntem gitmek için bir yol olacaktır.
mightybyte

Harika bir açıklama! Anlamadığım şey newtype, derleme ve çalışma zamanı eski ve yeni türler için aynı gösterimi kullandıktan sonra silinirse, yine de hem eski hem de yeni tür için örnekleri nasıl tanımlayabiliriz? Çalışma zamanı hangi örneği kullanacağını nasıl anlayabilir?
damluar

3
@damluar Tüm türler çalışma zamanında silinir, derleme zamanında tamamen çözülür ve derleme sırasında newtypehenüz silinmez.
noktalı virgül

3
@damlaur Bir zamanlar sizinle aynı soruyu sordum. İnsanlar türlerin silindiğini söylediklerinde, belirli bir veri parçası için hangi örnek yönteminin kullanılacağına karar vermek için sözlük aramalarında kullanılan bir bellek kelimesi olan bir şey ISS'T silinmediğinden bahsetmezler. İnsanlar bu sözcüğün sizin bakış açınıza bağlı olduğunu düşündüğüm bir "tür" olmadığını iddia ediyor, ama işte gidiyorsunuz.
Gabriel L.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.