Apa bedanya ketika saya menulis ini?
data Book = Book Int Int
melawan
newtype Book = Book (Int, Int) -- "Book Int Int" is syntactically invalid
haskell
types
type-systems
newtype
ewggwegw
sumber
sumber
newtype Book = Book Int Int
tidak valid. Namun Anda dapat,newtype Book = Book (Int, Int)
seperti yang dicatat oleh don di bawah ini.Jawaban:
Pertanyaan bagus!
Ada beberapa perbedaan utama.
Perwakilan
newtype
menjamin bahwa data Anda akan memiliki representasi yang sama persis saat runtime, seperti tipe yang Anda bungkus.data
mendeklarasikan struktur data baru saat runtime.Jadi titik kunci di sini adalah bahwa konstruksi untuk
newtype
dijamin akan dihapus pada waktu kompilasi.Contoh:
data Book = Book Int Int
newtype Book = Book (Int, Int)
Perhatikan bagaimana ia memiliki representasi yang sama persis dengan a
(Int,Int)
, karenaBook
konstruktor dihapus.data Book = Book (Int, Int)
Memiliki
Book
konstruktor tambahan tidak ada dalamnewtype
.data Book = Book {-# UNPACK #-}!Int {-# UNPACK #-}!Int
Tidak ada petunjuk! Dua
Int
bidang adalah bidang berukuran kata tanpa kotak di dalamBook
konstruktor.Tipe data aljabar
Karena kebutuhan ini untuk menghapus konstruktor,
newtype
hanya berfungsi ketika membungkus tipe data dengan konstruktor tunggal . Tidak ada gagasan tentang tipe baru "aljabar". Artinya, Anda tidak dapat menulis jenis baru yang setara dengan, katakanlah,karena memiliki lebih dari satu konstruktor. Anda juga tidak bisa menulis
Kekerasan
Fakta bahwa konstruktor dihapus mengarah ke beberapa perbedaan yang sangat halus dalam keketatan antara
data
dannewtype
. Secara khusus,data
memperkenalkan tipe yang "diangkat", yang berarti, pada dasarnya, ia memiliki cara tambahan untuk mengevaluasi ke nilai terbawah. Karena tidak ada konstruktor tambahan saat runtime dengannewtype
, properti ini tidak berlaku.Pointer ekstra di dalam
Book
to(,)
constructor memungkinkan kita untuk memasukkan nilai terbawah.Akibatnya,
newtype
dandata
memiliki sifat keketatan yang sedikit berbeda, seperti yang dijelaskan dalam artikel wiki Haskell .Buka kotak
Tidak masuk akal untuk membuka kotak komponen
newtype
, karena tidak ada konstruktor. Meskipun sangat masuk akal untuk menulis:menghasilkan objek runtime dengan
T
konstruktor, danInt#
komponen. Anda hanya mendapatkan telanjangInt
dengannewtype
.Referensi :
sumber
newtype
dihapus setelah kompilasi dan runtime menggunakan representasi yang sama untuk tipe lama dan baru, bagaimana kita masih dapat mendefinisikan instance untuk tipe lama dan baru? Bagaimana cara runtime memahami instance mana yang digunakan?newtype
jelas belum terhapus.