Di Elm, saya tidak tahu kapan type
adalah vs kata kunci yang sesuai type alias
. Dokumentasi tampaknya tidak memiliki penjelasan tentang ini, saya juga tidak dapat menemukannya di catatan rilis. Apakah ini didokumentasikan di suatu tempat?
Bagaimana saya memikirkannya:
type
digunakan untuk menentukan jenis serikat baru:
type Thing = Something | SomethingElse
Sebelum definisi ini Something
dan SomethingElse
tidak berarti apa-apa. Sekarang keduanya adalah tipe Thing
, yang baru saja kita definisikan.
type alias
digunakan untuk memberi nama pada beberapa tipe lain yang sudah ada:
type alias Location = { lat:Int, long:Int }
{ lat = 5, long = 10 }
memiliki tipe { lat:Int, long:Int }
, yang tadinya merupakan tipe yang valid. Tapi sekarang kita juga bisa mengatakan itu memiliki tipe Location
karena itu adalah alias untuk tipe yang sama.
Perlu dicatat bahwa berikut ini akan mengkompilasi dengan baik dan ditampilkan "thing"
. Meskipun kami menetapkan thing
adalah a String
dan aliasedStringIdentity
mengambil AliasedString
, kami tidak akan mendapatkan kesalahan bahwa ada jenis ketidakcocokan antara String
/ AliasedString
:
import Graphics.Element exposing (show)
type alias AliasedString = String
aliasedStringIdentity: AliasedString -> AliasedString
aliasedStringIdentity s = s
thing : String
thing = "thing"
main =
show <| aliasedStringIdentity thing
{}
sintaks record, Anda mendefinisikan tipe baru?{ lat:Int, long:Int }
tidak mendefinisikan tipe baru. Itu sudah tipe yang valid.type alias Location = { lat:Int, long:Int }
juga tidak mendefinisikan tipe baru, itu hanya memberi nama lain (mungkin lebih deskriptif) untuk tipe yang sudah valid.type Location = Geo { lat:Int, long:Int }
akan mendefinisikan tipe baru (Location
)Kuncinya adalah kata
alias
. Dalam kursus pemrograman, ketika Anda ingin mengelompokkan hal-hal yang menjadi satu, Anda memasukkannya ke dalam sebuah catatan, seperti dalam kasus sebuah poinatau catatan siswa.
Sekarang, jika Anda perlu menyebarkan record ini, Anda harus mengeja seluruh tipe, seperti:
Jika Anda bisa membuat alias sebuah titik, tanda tangannya akan jauh lebih mudah untuk ditulis!
Jadi alias adalah singkatan dari sesuatu yang lain. Di sini, ini adalah singkatan dari tipe rekaman. Anda dapat menganggapnya sebagai memberi nama untuk jenis rekaman yang akan sering Anda gunakan. Itulah mengapa ini disebut alias - ini adalah nama lain untuk tipe rekaman telanjang yang diwakili oleh
{ x:Int, y:Int }
Padahal
type
memecahkan masalah yang berbeda. Jika Anda berasal dari OOP, itu adalah masalah yang Anda selesaikan dengan warisan, kelebihan beban operator, dll. - terkadang, Anda ingin memperlakukan data sebagai hal yang umum, dan terkadang Anda ingin memperlakukannya seperti hal tertentu.Hal yang biasa terjadi adalah saat menyebarkan pesan - seperti sistem pos. Saat Anda mengirim surat, Anda ingin sistem pos memperlakukan semua pesan sebagai hal yang sama, jadi Anda hanya perlu merancang sistem pos sekali. Selain itu, tugas perutean pesan harus independen dari pesan yang terkandung di dalamnya. Hanya ketika surat itu mencapai tujuannya barulah Anda peduli tentang apa pesannya.
Dengan cara yang sama, kita dapat mendefinisikan a
type
sebagai gabungan dari semua jenis pesan berbeda yang dapat terjadi. Katakanlah kita menerapkan sistem pesan antara mahasiswa kepada orang tua mereka. Jadi hanya ada dua pesan yang dapat dikirim oleh anak-anak perguruan tinggi: 'Saya butuh uang bir' dan 'Saya butuh celana dalam'.Jadi sekarang, ketika kita mendesain sistem perutean, tipe untuk fungsi kita bisa begitu saja
MessageHome
, alih-alih mengkhawatirkan semua jenis pesan yang berbeda. Sistem perutean tidak peduli. Itu hanya perlu tahu itu aMessageHome
. Hanya ketika pesan mencapai tujuannya, rumah orang tua, Anda perlu mencari tahu apa itu.Jika Anda mengetahui arsitektur Elm, fungsi pembaruan adalah pernyataan kasus raksasa, karena itulah tujuan dari mana pesan dirutekan, dan karenanya diproses. Dan kami menggunakan tipe gabungan untuk memiliki satu tipe yang harus ditangani saat meneruskan pesan, tetapi kemudian dapat menggunakan pernyataan kasus untuk mengetahui pesan apa itu sebenarnya, sehingga kami dapat mengatasinya.
sumber
Izinkan saya melengkapi jawaban sebelumnya dengan berfokus pada kasus penggunaan dan memberikan sedikit konteks pada fungsi dan modul konstruktor.
Penggunaan
type alias
Membuat alias dan fungsi konstruktor untuk rekaman.
Ini kasus penggunaan yang paling umum: Anda dapat menentukan nama alternatif dan fungsi konstruktor untuk jenis format rekaman tertentu.
Mendefinisikan alias tipe secara otomatis menyiratkan fungsi konstruktor berikut (kode pseudo):
Person : String -> Int -> { name : String, age : Int }
Ini bisa berguna, misalnya ketika Anda ingin menulis dekoder Json.
Tentukan bidang wajib
Mereka terkadang menyebutnya "catatan yang dapat diperluas", yang dapat menyesatkan. Sintaks ini dapat digunakan untuk menentukan bahwa Anda mengharapkan beberapa record dengan field tertentu. Seperti:
Kemudian Anda dapat menggunakan fungsi di atas seperti ini (misalnya dalam tampilan Anda):
Pembicaraan Richard Feldman tentang ElmEurope 2017 dapat memberikan wawasan lebih jauh tentang kapan gaya ini layak digunakan.
Mengganti nama barang
Anda dapat melakukan ini, karena nama baru dapat memberikan arti tambahan di kemudian hari dalam kode Anda, seperti dalam contoh ini
Mungkin contoh yang lebih baik dari jenis penggunaan inti ini adalah
Time
.Mengekspos ulang tipe dari modul lain
Jika Anda menulis sebuah paket (bukan aplikasi), Anda mungkin perlu mengimplementasikan tipe dalam satu modul, mungkin dalam modul internal (tidak terekspos), tetapi Anda ingin mengekspos tipe dari modul yang berbeda (publik). Atau, sebagai alternatif, Anda ingin mengekspos tipe Anda dari beberapa modul.
Task
di inti dan Http.Request di Http adalah contoh untuk yang pertama, sedangkan pasangan Json.Encode.Value dan Json.Decode.Value adalah contoh di kemudian hari.Anda hanya dapat melakukan ini jika sebaliknya Anda ingin mempertahankan tipe buram: Anda tidak mengekspos fungsi konstruktor. Untuk detailnya lihat penggunaan di
type
bawah ini.Perlu diperhatikan bahwa dalam contoh di atas hanya # 1 yang menyediakan fungsi konstruktor. Jika Anda mengekspos alias tipe Anda di # 1 seperti
module Data exposing (Person)
itu akan mengekspos nama tipe serta fungsi konstruktor.Penggunaan
type
Definisikan tipe serikat yang diberi tag
Ini adalah kasus penggunaan yang paling umum, contoh yang baik adalah
Maybe
tipe dalam inti :Saat Anda mendefinisikan sebuah tipe, Anda juga mendefinisikan fungsi konstruktornya. Dalam kasus Maybe ini adalah (pseudo-code):
Artinya jika Anda mendeklarasikan nilai ini:
Anda dapat membuatnya dengan salah satunya
atau
The
Just
danNothing
tag tidak hanya berfungsi sebagai fungsi konstruktor, mereka juga berfungsi sebagai destructors atau pola dalamcase
berekspresi. Yang berarti bahwa menggunakan pola-pola ini Anda dapat melihat di dalam aMaybe
:Anda dapat melakukan ini, karena modul Maybe didefinisikan seperti
Bisa juga dikatakan
Keduanya setara dalam kasus ini, tetapi menjadi eksplisit dianggap kebajikan di Elm, terutama saat Anda menulis paket.
Menyembunyikan detail implementasi
Seperti yang ditunjukkan di atas, ini adalah pilihan yang disengaja bahwa fungsi konstruktor
Maybe
terlihat untuk modul lain.Namun, ada kasus lain ketika penulis memutuskan untuk menyembunyikannya. Salah satu contohnya adalah
Dict
. Sebagai pengguna paket, Anda seharusnya tidak dapat melihat detail implementasi algoritma pohon Merah / Hitam di belakangDict
dan mengacaukan node secara langsung. Menyembunyikan fungsi konstruktor memaksa konsumen modul / paket Anda untuk hanya membuat nilai jenis Anda (dan kemudian mengubah nilai tersebut) melalui fungsi yang Anda tunjukkan.Inilah alasan mengapa terkadang hal-hal seperti ini muncul dalam kode
Tidak seperti
type alias
definisi di bagian atas posting ini, sintaks ini membuat jenis "gabungan" baru dengan hanya satu fungsi konstruktor, tetapi fungsi konstruktor tersebut dapat disembunyikan dari modul / paket lain.Jika tipenya diekspos seperti ini:
Hanya kode dalam
Data
modul yang dapat membuat nilai Person dan hanya kode tersebut yang dapat mencocokkan pola padanya.sumber
Perbedaan utama, menurut saya, adalah apakah pemeriksa tipe akan berteriak pada Anda jika Anda menggunakan tipe "sinomis".
Buat file berikut, letakkan di suatu tempat dan jalankan
elm-reactor
, lalu bukahttp://localhost:8000
untuk melihat perbedaannya:Jika Anda menghapus komentar
2.
dan berkomentar,1.
Anda akan melihat:sumber
An
alias
hanyalah nama pendek untuk beberapa tipe lainnya, serupaclass
di OOP. Kedaluwarsa:Sebuah
type
(tanpa alias) akan membiarkan Anda menentukan jenis Anda sendiri, sehingga Anda dapat menentukan jenis sepertiInt
,String
, ... untuk Anda aplikasi. Sebagai contoh, dalam kasus umum, ini bisa digunakan untuk mendeskripsikan status aplikasi:Jadi Anda dapat dengan mudah menanganinya di
view
elm:Saya pikir Anda tahu perbedaan antara
type
dantype alias
.Tapi mengapa dan bagaimana menggunakan
type
dantype alias
penting denganelm
aplikasi, kalian dapat merujuk artikel dari Josh Claytonsumber