Apa perbedaan antara jenis dan jenis?


26

Saya belajar bahasa pemrograman Haskell, dan saya mencoba untuk membungkus kepala saya di sekitar apa perbedaan antara a typedan a kind.

Seperti yang saya pahami a kind is a type of type,. Misalnya, a ford is a type of cardan a car is a kind of vehicle.

Apakah ini cara yang baik untuk memikirkan hal ini?

Karena, cara otak saya saat ini terhubung ford is a **type** of car, tetapi juga car is a **type** of vehiclesementara pada saat yang sama a car is a **kind** of vehicle. Yaitu persyaratan typedan kinddapat dipertukarkan.

Adakah yang bisa menjelaskan hal ini?


6
Saya baru saja datang ke sini dari pos di Stack Overflow yang menyebabkan diskusi ini. Saya tidak yakin saya memenuhi syarat untuk menjawab secara rinci - tetapi Anda pasti terlalu harfiah tentang istilah "jenis" dan "jenis", dalam mencoba menghubungkannya dengan makna mereka dalam bahasa Inggris (di mana memang mereka sinonim ). Anda harus memperlakukan mereka sebagai ketentuan teknis. "Tipe" dipahami dengan baik oleh semua pemrogram, saya berasumsi, karena konsep ini sangat penting untuk setiap bahasa, bahkan yang diketik dengan lemah seperti Javascript, "Jenis" adalah istilah teknis yang digunakan di Haskell untuk "tipe tipe". Itu benar-benar semua yang ada untuk itu.
Robin Zigmond

2
@RobinZigmond: Anda benar karena ini adalah istilah teknis, tetapi mereka digunakan lebih luas daripada hanya di Haskell. Mungkin backlink ke diskusi Stack Overflow yang menimbulkan pertanyaan ini?
Andrej Bauer

@AndrejBauer Saya tidak pernah mengatakan bahwa mereka tidak digunakan di luar Haskell, tentu "tipe" digunakan pada dasarnya setiap bahasa, seperti yang saya katakan. Saya tidak pernah benar-benar menemukan "jenis" di luar Haskell, tetapi kemudian Haskell adalah satu-satunya bahasa fungsional yang saya tahu sama sekali, dan saya berhati-hati untuk tidak mengatakan istilah itu tidak digunakan di tempat lain, hanya saja itu digunakan dengan cara seperti itu di Haskell. (Dan tautannya, seperti yang Anda minta, ada di sini )
Robin Zigmond

Bahasa ML-family juga memiliki jenis, misalnya Standard ML dan OCaml. Mereka tidak terpapar secara eksplisit dengan nama itu, saya pikir. Mereka dimanifestasikan sebagai tanda tangan , dan elemen mereka disebut struktur .
Andrej Bauer

1
Analogi bahasa Inggris yang lebih akurat adalah Ford adalah tipe mobil dan mobil adalah tipe kendaraan tetapi tipe mobil dan tipe kendaraan adalah jenis yang sama: kata benda. Sedangkan merah adalah jenis warna mobil dan RPM adalah jenis metrik kinerja mobil dan keduanya memiliki jenis yang sama: kata sifat.
slebetman

Jawaban:


32

Di sini, "nilai", "tipe", dan "jenis" memiliki arti formal, jadi mempertimbangkan penggunaan umum dalam bahasa Inggris atau analogi untuk mengklasifikasikan mobil hanya akan membuat Anda sejauh ini.

Jawaban saya berkaitan dengan makna formal dari istilah-istilah ini dalam konteks Haskell secara khusus; makna ini didasarkan pada (meskipun tidak benar-benar identik dengan) makna yang digunakan dalam matematika / CS "teori tipe". Jadi, ini bukan jawaban "ilmu komputer" yang sangat bagus, tetapi seharusnya berfungsi sebagai jawaban Haskell yang cukup bagus.

Dalam Haskell (dan bahasa lainnya), pada akhirnya membantu untuk menetapkan jenis ekspresi program yang menjelaskan kelas nilai yang diizinkan dimiliki oleh ekspresi tersebut. Saya berasumsi di sini bahwa Anda telah melihat cukup banyak contoh untuk memahami mengapa akan berguna untuk mengetahui bahwa dalam ekspresi sqrt (a**2 + b**2), variabel adan bakan selalu menjadi nilai tipe Doubledan tidak, katakanlah, Stringdan Boolmasing - masing. Pada dasarnya, memiliki tipe membantu kita dalam menulis ekspresi / program yang akan bekerja dengan benar pada berbagai nilai .

Sekarang, sesuatu yang mungkin tidak Anda sadari adalah bahwa tipe Haskell, seperti yang muncul dalam tanda tangan tipe:

fmap :: Functor f => (a -> b) -> f a -> f b

sebenarnya sendiri ditulis dalam sub-bahasa Haskell tipe-level. Teks program Functor f => (a -> b) -> f a -> f badalah - secara harfiah - ekspresi tipe yang ditulis dalam subbahasa ini. Sub-bahasa termasuk operator (misalnya, ->adalah operator infiks asosiatif yang tepat dalam bahasa ini), variabel (misalnya, f, a, dan b), dan "aplikasi" dari satu jenis ekspresi yang lain (misalnya, f ayang fditerapkan untuk a).

Apakah saya menyebutkan bagaimana membantu dalam banyak bahasa untuk menetapkan tipe ekspresi program untuk menggambarkan kelas nilai ekspresi? Nah, dalam subtitle bahasa tingkat-jenis ini, ekspresi mengevaluasi ke tipe (bukan nilai ) dan pada akhirnya membantu untuk menetapkan jenis untuk mengetik ekspresi untuk menggambarkan kelas tipe yang diizinkan untuk mereka wakili. Pada dasarnya, memiliki jenis membantu kita dalam menulis ekspresi tipe yang akan bekerja dengan benar pada berbagai jenis .

Jadi, nilai adalah tipe karena tipe adalah jenis , dan tipe membantu kita menulis program tingkat- nilai sementara jenis membantu kita menulis program tipe- tingkat.

Apa ini jenis terlihat seperti? Nah, pertimbangkan jenis tanda tangan:

id :: a -> a

Jika ekspresi jenis a -> aadalah sah, apa jenis dari jenis yang harus kita mengizinkan variabel auntuk menjadi? Nah, jenis ekspresi:

Int -> Int
Bool -> Bool

terlihat valid, jadi tipe Int dan Booljelas dari jenis yang tepat . Tetapi jenis yang lebih rumit seperti:

[Double] -> [Double]
Maybe [(Double,Int)] -> Maybe [(Double,Int)]

terlihat valid Bahkan, karena kita harus dapat memanggil idfungsi, bahkan:

(a -> a) -> (a -> a)

terlihat baik-baik saja. Jadi, Int, Bool, [Double], Maybe [(Double,Int)], dan a -> asemua terlihat seperti jenis hak jenis .

Dengan kata lain, sepertinya hanya ada satu jenis , sebut saja *seperti wildcard Unix, dan setiap jenis memiliki jenis yang sama *, akhir cerita.

Kanan?

Ya tidak cukup. Ternyata Maybe, dengan sendirinya, adalah ekspresi tipe yang valid Maybe Int(dalam banyak hal yang sama sqrt, semua dengan sendirinya, sama validnya dengan ekspresi nilai sqrt 25). Namun , ekspresi tipe berikut ini tidak valid:

Maybe -> Maybe

Karena, sementara Maybeadalah ekspresi jenis, itu tidak mewakili jenis dari jenis yang dapat memiliki nilai-nilai. Jadi, itulah bagaimana kita harus mendefinisikan *- itu adalah jenis dari jenis yang memiliki nilai-nilai; itu termasuk tipe "lengkap" seperti Doubleatau Maybe [(Double,Int)]tetapi tidak termasuk tipe tidak lengkap dan tidak berharga seperti Either String. Untuk kesederhanaan, saya akan menyebut tipe lengkap ini sebagai *"tipe konkret", meskipun terminologi ini tidak universal, dan "tipe konkret" mungkin berarti sesuatu yang sangat berbeda dengan, katakanlah, seorang programmer C ++.

Sekarang, dalam ekspresi jenis a -> a, selama jenis amemiliki jenis * (jenis jenis beton), hasil dari ekspresi jenis jugaa -> a akan memiliki jenis (yaitu, jenis jenis beton). *

Jadi, apa jenis dari jenis ini Maybe? Nah, Maybebisa diterapkan pada jenis beton untuk menghasilkan jenis beton lain. Jadi, Maybetampak seperti sedikit seperti fungsi jenis-tingkat yang mengambil jenis dari jenis * dan mengembalikan jenis dari jenis * . Jika kita memiliki fungsi tingkat nilai yang mengambil nilai dari jenis Int dan kembali nilai dari jenis Int , kami akan memberikan jenis tanda tangan Int -> Int, sehingga dengan analogi kita harus memberikan Maybesebuah jenis tanda tangan * -> *. GHCi setuju:

> :kind Maybe
Maybe :: * -> *

Kembali ke:

fmap :: Functor f => (a -> b) -> f a -> f b

Dalam jenis tanda tangan ini, variabel fmemiliki jenis * -> *dan variabel adan bjenis *; operator bawaan ->memiliki jenis * -> * -> *(dibutuhkan jenis *di sebelah kiri dan satu di kanan dan mengembalikan jenis juga *). Dari ini dan aturan inferensi jenis, Anda dapat menyimpulkan bahwa itu a -> badalah jenis yang valid dengan jenis *, f adan f bjuga jenis yang valid dengan jenis *, dan (a -> b) -> f a -> f bjenis jenis yang valid *.

Dengan kata lain, kompiler dapat "jenis memeriksa" ekspresi tipe (a -> b) -> f a -> f buntuk memverifikasi itu valid untuk jenis variabel dari jenis yang tepat dengan cara yang sama "ketik memeriksa" sqrt (a**2 + b**2)untuk memverifikasi itu valid untuk variabel dari jenis yang tepat.

Alasan untuk menggunakan istilah terpisah untuk "jenis" versus "jenis" (yaitu, tidak berbicara tentang "jenis jenis") sebagian besar hanya untuk menghindari kebingungan. The jenis di atas tampilan yang sangat berbeda dari jenis dan, setidaknya pada awalnya, tampaknya berperilaku cukup berbeda. (Sebagai contoh, dibutuhkan beberapa waktu untuk membungkus kepala Anda sekitar gagasan bahwa setiap "normal" jenis memiliki jenis yang sama *dan jenis a -> byang *tidak * -> *.)

Beberapa di antaranya juga historis. Ketika GHC Haskell telah berevolusi, perbedaan antara nilai, tipe, dan jenis sudah mulai kabur. Hari-hari ini, nilai-nilai dapat "dipromosikan" ke dalam tipe, dan tipe dan jenis adalah hal yang sama. Jadi, di Haskell modern, nilai keduanya memiliki tipe dan tipe ARE (hampir), dan jenis-jenisnya hanyalah tipe yang lebih banyak.

@ user21820 meminta beberapa penjelasan tambahan tentang "jenis dan jenisnya adalah hal yang sama". Untuk menjadi sedikit lebih jelas, dalam GHC Haskell modern (sejak versi 8.0.1, saya pikir), jenis dan jenis diperlakukan secara seragam di sebagian besar kode kompiler. Kompiler melakukan upaya dalam pesan kesalahan untuk membedakan antara "jenis" dan "jenis", tergantung pada apakah itu mengeluh tentang jenis nilai atau jenis jenis, masing-masing.

Juga, jika tidak ada ekstensi yang diaktifkan, ekstensi tersebut mudah dibedakan dalam bahasa permukaan. Sebagai contoh, tipe (nilai) memiliki representasi dalam sintaks (misalnya, dalam tipe tanda tangan), tetapi jenis (tipe) adalah - saya pikir - sepenuhnya tersirat, dan tidak ada sintaksis eksplisit di mana mereka muncul.

Tetapi, jika Anda mengaktifkan ekstensi yang sesuai, perbedaan antara jenis dan jenis sebagian besar menghilang. Sebagai contoh:

{-# LANGUAGE GADTs, TypeInType #-}
data Foo where
  Bar :: Bool -> * -> Foo

Di sini, Baradalah (baik nilai dan) tipe. Sebagai jenis, jenisnya adalah Bool -> * -> Foo, yang merupakan fungsi tipe-tingkat yang mengambil jenis jenis Bool(yang merupakan jenis, tetapi juga jenis) dan jenis jenis *dan menghasilkan jenis jenis Foo. Begitu:

type MyBar = Bar True Int

memeriksa dengan benar.

Sebagai @AndrejBauer menjelaskan dalam jawabannya, kegagalan untuk membedakan antara jenis dan jenis tidak aman - memiliki jenis / jenis *yang jenis / jenisnya itu sendiri (yang merupakan kasus di Haskell modern) mengarah ke paradoks. Namun, sistem tipe Haskell sudah penuh dengan paradoks karena non-terminasi, sehingga tidak dianggap sebagai masalah besar.


Jika "jenis dan jenisnya benar-benar hal yang sama", maka jenisnya typehanyalah typedirinya sendiri, dan tidak perlu sama sekali kind. Jadi apa tepatnya perbedaannya?
user21820

1
@ user21820, saya menambahkan catatan ke bagian akhir yang mungkin membahas hal ini. Jawaban singkat: tidak ada perbedaan dalam GHC Haskell modern .
KA Buhr

1
Ini jawaban yang bagus - terima kasih banyak sudah berbagi. Ini ditulis dengan baik dan memperkenalkan konsep secara bertahap - sebagai seseorang yang belum menulis Haskell selama beberapa tahun, ini sangat dihargai!
ultrafez

@ Kuhuhr: Terima kasih untuk itu sedikit ditambahkan!
user21820

19

tyhale:ksayand=set:clSebuahss.

  • Bool adalah tipe
  • Type adalah sejenis karena unsur-unsurnya adalah jenis
  • Bool -> Int adalah tipe
  • Bool -> Type adalah sejenis karena elemen-elemennya adalah fungsi yang mengembalikan tipe
  • Bool * Int adalah tipe
  • Bool * Type adalah sejenis karena unsur-unsurnya berpasangan dengan satu komponen jenis

U0U1U2U0BHaiHailNSebuahtNSebuahtNSebuahtU1U0BHaiHailU0U0U0Un+1UnUn×

U0U1U0U1U0**U_1


2
Saya tidak berpikir (GHC) Haskell memiliki konsep semesta. Type :: Typeadalah sebuah aksioma. Perbedaan antara "tipe" dan "jenis" sepenuhnya dalam bahasa manusia, dalam hal ini. Truememiliki tipe,, Booldan Boolmemiliki tipe Type, yang tipe itu sendiri Type. Kadang-kadang kita menyebut jenis tipe, untuk menekankan bahwa itu adalah tipe entitas tipe-level, tetapi, di Haskell, itu masih hanya tipe. Dalam sebuah sistem di mana alam semesta benar-benar ada, seperti Coq, maka "tipe" dapat merujuk ke satu alam semesta dan "jenis" yang lain, tetapi kemudian kita biasanya menginginkan banyak alam semesta yang tak terhingga banyaknya.
HTNW

1
Perbedaannya bukan hanya "bahasa manusia", itu adalah perbedaan formal dalam sistem tipe yang mendasarinya. Sangat mungkin untuk memiliki keduanya Type :: Typedan perbedaan antara jenis dan jenis. Selain itu, potongan kode apa yang diperagakan Type :: Typedi Haskell?
Andrej Bauer

1
Saya juga harus mengatakan bahwa *di Haskell adalah semacam semesta. Mereka hanya tidak menyebutnya begitu.
Andrej Bauer

3
@AndrejBauer Typedari Data.Kindsdan *harus sinonim. Awalnya kami hanya memiliki *sebagai primitif, sementara saat ini yang didefinisikan GHC.Types.Typesecara internal dalam modul internal GHC.Types, pada gilirannya didefinisikan sebagai type Type = TYPE LiftedRep. Saya pikir TYPEadalah primitif nyata, menyediakan keluarga jenis (tipe lift, tipe unboxed, ...). Sebagian besar kompleksitas "inelegant" di sini adalah untuk mendukung beberapa optimasi tingkat rendah, dan bukan untuk alasan teoretik tipe aktual.
chi

1
Saya akan mencoba meringkas. Jika vadalah nilai, maka ia memiliki tipe: v :: T. Jika Tadalah tipe, maka ia memiliki tipe: T :: K. Jenis jenis ini disebut jenisnya. Jenis yang terlihat seperti TYPE repbisa disebut macam, meskipun kata itu tidak umum. IFF T :: TYPE repadalah Tdiizinkan untuk tampil di RHS dari ::. Kata "jenis" memiliki nuansa padanya: Kin T :: Kadalah sejenis, tetapi tidak dalam v :: K, meskipun sama K. Kita dapat mendefinisikan " Kadalah jenis jika jenisnya adalah jenis" alias "jenisnya ada di RHS ::", tetapi itu tidak menangkap penggunaannya dengan benar. Karena itu posisi "perbedaan manusia" saya.
HTNW

5

Sebuah nilai adalah seperti spesifik merah 2011 Ford Mustang dengan 19.206 mil di atasnya bahwa Anda telah duduk di halaman Anda.

Nilai spesifik itu, secara informal, dapat memiliki banyak jenis : itu adalah Mustang, dan itu adalah Ford, dan itu adalah sebuah mobil, dan itu adalah sebuah kendaraan, di antara banyak jenis lainnya yang dapat Anda hasilkan (jenis "barang" milik Anda ", atau jenis" hal-hal yang berwarna merah ", atau ...).

(Di Haskell, ke perkiraan orde pertama (GADT menghancurkan properti ini, dan keajaiban di sekitar literal angka dan ekstensi OverloadedStrings mengaburkan sedikit), nilai memiliki satu jenis utama alih-alih kebanyakan "jenis" informal yang dapat Anda berikan kepada Anda ' stang. 42, adalah untuk tujuan penjelasan ini, sebuah Int; tidak ada jenis dalam Haskell untuk "angka" atau "bahkan bilangan bulat" —atau lebih tepatnya, Anda bisa membuatnya, tetapi itu akan menjadi tipe terpisah dari Int.)

Sekarang, "Mustang" mungkin merupakan subtipe dari "mobil" - setiap nilai yang merupakan Mustang juga merupakan mobil. Tetapi tipe —atau, untuk menggunakan terminologi Haskell, jenis "Mustang" bukanlah "mobil". "Mustang" jenisnya bukanlah sesuatu yang bisa Anda parkirkan di jalan masuk atau berkeliling. "Mustang" adalah kata benda, atau kategori, atau hanya tipe. Itu adalah, secara informal, jenis - jenis "Mustang".

(Lagi-lagi, Haskell hanya mengenali satu jenis untuk setiap hal level-jenis. Begitu Intjuga jenis *, dan tidak ada jenis lain, Maybememiliki jenis * -> *, dan tidak ada jenis lain. Tetapi intuisi masih harus dipegang: 42adalah Int, dan Anda dapat melakukan Inthal-hal dengan itu. seperti menambah dan mengurangi, Intitu sendiri bukan suatu Int; tidak ada angka seperti itu Int + Int. Anda dapat secara informal mendengar orang mengatakan bahwa itu Intadalah Num, yang berarti bahwa ada turunan dari Numtipe kelas untuk tipe Int— ini bukan hal yang sama mengatakan bahwa yang Intmemiliki jenis Num . Intmemiliki jenis "jenis", yang dalam Haskell dieja *.)

Jadi bukankah setiap "tipe" informal hanya berupa kata benda atau kategori? Apakah semua jenis memiliki jenis yang sama? Mengapa berbicara tentang jenis sama sekali jika mereka sangat membosankan?

Di sinilah analogi bahasa Inggris akan menjadi sedikit berbatu, tetapi bersabarlah: berpura-pura bahwa kata "pemilik" dalam bahasa Inggris tidak masuk akal secara terpisah, tanpa uraian tentang benda yang dimiliki. Berpura-puralah bahwa jika seseorang menyebut Anda "pemilik", itu sama sekali tidak masuk akal bagi Anda; tetapi jika seseorang memanggil Anda "pemilik mobil", Anda bisa mengerti apa artinya.

"Pemilik" tidak memiliki jenis yang sama dengan "mobil", karena Anda dapat berbicara tentang mobil, tetapi Anda tidak dapat berbicara tentang pemilik dalam versi bahasa Inggris yang dibuat-buat ini. Anda hanya dapat berbicara tentang "pemilik mobil". "Pemilik" hanya menciptakan sesuatu yang seperti "kata benda" ketika diterapkan pada sesuatu yang sudah memiliki "kata benda", seperti "mobil". Kami akan mengatakan bahwa jenis "pemilik" adalah "kata benda -> kata benda". "Pemilik" seperti fungsi yang mengambil kata benda dan menghasilkan dari kata benda yang berbeda; tapi itu bukan kata benda itu sendiri.

Perhatikan bahwa "pemilik mobil" bukan subtipe "mobil"! Ini bukan fungsi yang menerima atau mengembalikan mobil! Itu hanya tipe yang sepenuhnya terpisah dari "mobil". Ini menggambarkan nilai-nilai dengan dua tangan dan dua kaki yang pada satu titik memiliki sejumlah uang tertentu, dan membawa uang itu ke dealer. Itu tidak menggambarkan nilai-nilai yang memiliki empat roda dan pekerjaan cat. Juga perhatikan bahwa "pemilik mobil" dan "pemilik anjing" adalah tipe yang berbeda, dan hal-hal yang mungkin ingin Anda lakukan dengan satu mungkin tidak berlaku untuk yang lain.

(Demikian juga, ketika kita mengatakan bahwa Maybememiliki jenis * -> *Haskell, yang kita maksud adalah tidak masuk akal (secara formal; secara informal kita melakukannya sepanjang waktu) untuk berbicara tentang memiliki "a Maybe". Sebaliknya, kita dapat memiliki Maybe Intatau Maybe String, karena itu adalah hal-hal dari baik *.)

Jadi inti dari berbicara tentang jenis sama sekali adalah agar kita dapat memformalisasikan penalaran kita di sekitar kata-kata seperti "pemilik" dan menegakkan bahwa kita hanya pernah mengambil nilai-nilai jenis yang telah "sepenuhnya dibangun" dan tidak masuk akal.


1
Saya tidak mengatakan bahwa analogi Anda salah, tetapi saya pikir itu dapat menyebabkan kebingungan. Dijkstra memiliki beberapa kata tentang analogi. Google "Pada kekejaman yang benar-benar mengajarkan ilmu komputasi".
Rafael Castro

Maksud saya, ada analogi mobil, dan kemudian ada analogi mobil. Saya tidak berpikir bahwa menyoroti struktur tipe implisit dalam bahasa alami (yang, memang, saya lakukan peregangan di babak kedua) sebagai cara untuk menjelaskan sistem tipe formal adalah jenis pengajaran-melalui-analogi yang sama seperti berbicara tentang apa program "ingin" lakukan.
user11228628

1

Seperti yang saya pahami, jenis adalah jenis tipe.

Itu benar - jadi mari kita jelajahi apa artinya itu. Intatau Texttipe konkret, tetapi Maybe amerupakan tipe abstrak . Itu tidak akan menjadi tipe konkret sampai Anda memutuskan nilai spesifik apa yang Anda inginkan untuk avariabel tertentu (atau nilai / ekspresi / apa pun) misalnya Maybe Text.

Kami mengatakan bahwa itu Maybe aadalah konstruktor tipe karena itu seperti fungsi yang mengambil tipe beton tunggal (misalnya Text) dan mengembalikan tipe beton ( Maybe Textdalam hal ini). Tetapi konstruktor tipe lain mungkin mengambil lebih banyak "params input" sebelum mereka mengembalikan tipe konkret. mis. Map k vperlu mengambil dua jenis beton (misalnya Intdan Text) sebelum dapat membangun jenis beton ( Map Int Text).

Jadi, konstruktor Maybe adan List aketik memiliki "tanda tangan" yang sama dengan yang kami tunjukkan * -> *(mirip dengan tanda tangan fungsi Haskell) karena jika Anda memberi mereka satu jenis beton, mereka akan memuntahkan jenis beton. Kami menyebutnya "jenis" dari jenis dan Maybedan Listmemiliki jenis yang sama.

Jenis beton dikatakan memiliki jenis *, dan contoh Peta kami adalah jenis * -> * -> *karena dibutuhkan dua jenis beton sebagai input sebelum dapat menghasilkan jenis beton.

Anda dapat melihatnya sebagian besar hanya tentang jumlah "parameter" yang kami sampaikan ke konstruktor tipe - tetapi menyadari bahwa kami mungkin juga mendapatkan konstruktor tipe yang bersarang di dalam konstruktor tipe, sehingga kami dapat berakhir dengan jenis yang terlihat seperti * -> (* -> *) -> *misalnya .

Jika Anda seorang Scala / pengembang Java, Anda juga dapat menemukan penjelasan ini bermanfaat: https://www.atlassian.com/blog/archives/scala-types-of-a-higher-kind


Ini tidak benar. Dalam Haskell, kita membedakan antara Maybe a, sinonim untuk forall a. Maybe a, jenis jenis polimorfik *, dan Maybe, jenis jenis monomorfik * -> *.
b0fh
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.