เอาล่ะเราไปทีละคนกัน
ค่า
ค่าคือชิ้นส่วนที่เป็นรูปธรรมของข้อมูลที่โปรแกรมประเมินและเล่นปาหี่ ไม่มีอะไรแฟนซีบางตัวอย่างอาจเป็น
1
true
"fizz buzz foo bar"
ประเภท
คำอธิบายที่ดีสำหรับประเภทคือ "ตัวแยกประเภทสำหรับค่า" ชนิดเป็นข้อมูลเล็กน้อยเกี่ยวกับค่าที่จะเป็นแบบรันไทม์ แต่ถูกระบุในเวลาคอมไพล์
ตัวอย่างเช่นถ้าคุณบอกฉันว่าe : bool
เวลารวบรวมและฉันจะรู้ว่าe
เป็นอย่างใดอย่างหนึ่งtrue
หรือfalse
ในช่วงรันไทม์ไม่มีอะไรอื่น! เนื่องจากประเภทแบ่งประเภทค่าอย่างนี้เราสามารถใช้ข้อมูลนี้เพื่อกำหนดคุณสมบัติพื้นฐานของโปรแกรมของคุณ
ตัวอย่างเช่นถ้าฉันเคยเห็นคุณเพิ่มe
และe'
เวลาe : int
และe' : String
จากนั้นฉันรู้ว่าบางสิ่งบางอย่างออกไปเล็กน้อย! ในความเป็นจริงฉันสามารถตั้งค่าสถานะนี้และโยนข้อผิดพลาดในเวลารวบรวมโดยพูดว่า "เฮ้นั่นมันไม่เข้าท่าเลย!"
ระบบประเภทที่ทรงพลังยิ่งกว่าจะช่วยให้ประเภทที่น่าสนใจมากขึ้นซึ่งจำแนกค่าที่น่าสนใจมากขึ้น ตัวอย่างเช่นลองพิจารณาฟังก์ชั่นบางอย่าง
f = fun x -> x
เป็นที่ชัดเจนว่าf : Something -> Something
แต่สิ่งที่ควรSomething
จะเป็นอย่างไร Something = int
ในระบบการพิมพ์ที่น่าเบื่อเราจะต้องระบุบางสิ่งบางอย่างโดยพลการเช่น ในระบบประเภทที่ยืดหยุ่นกว่านี้เราสามารถพูดได้
f : forall a. a -> a
นั่นคือการบอกว่า "สำหรับการใด ๆa
, f
แผนที่a
ไปยังa
" สิ่งนี้ให้เราใช้งานได้f
ทั่วไปมากขึ้นและเขียนโปรแกรมที่น่าสนใจมากขึ้น
ยิ่งไปกว่านั้นคอมไพเลอร์จะตรวจสอบความพึงพอใจของลักษณนามที่เราได้รับจริงถ้าหากf = fun x -> true
เรามีข้อผิดพลาดและคอมไพเลอร์จะพูดอย่างนั้น!
ดังนั้นในฐานะ tldr; type เป็นข้อ จำกัด เวลาในการรวบรวมค่าที่ expression สามารถทำได้ในขณะทำงาน
ตัวสร้างประเภท
บางประเภทเกี่ยวข้องกัน ตัวอย่างเช่นรายการจำนวนเต็มคล้ายกับรายการสตริง นี่เป็นเหมือนวิธีsort
การจำนวนเต็มเกือบจะเหมือนsort
สตริง เราสามารถจินตนาการประเภทของโรงงานที่สร้างประเภทเกือบจะเหมือนกันเหล่านี้โดยการสรุปความแตกต่างและสร้างตามความต้องการ นั่นคือสิ่งที่ตัวสร้างประเภทคือ มันเป็นเหมือนฟังก์ชั่นจากประเภทถึงประเภท แต่มีข้อ จำกัด มากกว่าเล็กน้อย
ตัวอย่างคลาสสิกเป็นรายการทั่วไป ตัวสร้างประเภทสำหรับเป็นเพียงคำจำกัดความทั่วไป
data List a = Cons a (List a) | Nil
ตอนนี้List
เป็นฟังก์ชั่นที่แมปประเภทa
กับรายการค่าประเภทนั้น! ใน Java-land ฉันคิดว่าสิ่งเหล่านี้อาจเรียกว่า "คลาสทั่วไป"
พารามิเตอร์ประเภท
พารามิเตอร์ type เป็นเพียงประเภทที่ส่งผ่านไปยังตัวสร้างประเภท (หรือฟังก์ชัน) เช่นเดียวกับในระดับค่าที่เราจะบอกว่าfoo(a)
มีพารามิเตอร์a
เช่นเดียวกับวิธีมีพารามิเตอร์ชนิดList a
a
ชนิด
ชนิดค่อนข้างยุ่งยาก แนวคิดพื้นฐานคือบางประเภทมีความคล้ายคลึงกัน ตัวอย่างเช่นเรามีทุกชนิดดั้งเดิมใน java int
, char
, float
... ซึ่งประพฤติทุกราวกับว่าพวกเขามี "พิมพ์" เดียวกัน ยกเว้นเมื่อเราพูดถึงตัวแยกประเภทสำหรับประเภทเองเราเรียกชนิดของตัวแยกประเภท ดังนั้นint : Prim
, ,String : Box
List : Boxed -> Boxed
ระบบนี้ให้กฎที่เป็นรูปธรรมที่ดีเกี่ยวกับประเภทประเภทที่เราสามารถใช้ได้ตรงที่เหมือนกับประเภทที่ควบคุมค่า เห็นได้ชัดว่ามันไร้สาระที่จะพูด
List<List>
หรือ
List<int>
ใน Java List
จำเป็นต้องใช้กับชนิดที่เป็นรูปธรรมเพื่อใช้เช่นนั้น! ถ้าเราดูชนิดของมันList : Boxed -> Boxed
และตั้งแต่Boxed -> Boxed /= Boxed
ข้างต้นเป็นข้อผิดพลาดชนิด!
เวลาส่วนใหญ่เราไม่ได้คิดเกี่ยวกับชนิดและเพียงแค่ถือว่าพวกเขาเป็น "สามัญสำนึก" แต่ด้วยระบบประเภทนักเล่นมันเป็นสิ่งสำคัญที่จะคิดเกี่ยวกับ
ภาพประกอบเล็ก ๆ น้อย ๆ ของสิ่งที่ฉันพูดไป
value : type : kind : ...
true : bool : Prim : ...
new F() : Foo : Boxed : ...
อ่านดีกว่าวิกิพีเดีย
หากคุณสนใจสิ่งนี้ฉันขอแนะนำให้ลงทุนในตำราเรียนที่ดี ทฤษฎีประเภทและ PLT โดยทั่วไปนั้นค่อนข้างกว้างใหญ่และไม่มีความรู้พื้นฐานที่สอดคล้องกันคุณ (หรืออย่างน้อยฉัน) สามารถเดินไปรอบ ๆ ได้โดยไม่ต้องไปไหนมาหลายเดือน
หนังสือเล่มโปรดสองเล่มของฉันคือ
- ประเภทและภาษาการเขียนโปรแกรม - Ben Pierce
- พื้นฐานการปฏิบัติของภาษาโปรแกรม - Bob Harper
ทั้งคู่เป็นหนังสือที่ยอดเยี่ยมที่แนะนำสิ่งที่ฉันเพิ่งพูดถึงและอื่น ๆ อีกมากมายในรายละเอียดที่สวยงามมีการอธิบายที่ดี