ผมขอชดเชยความสับสนนี้ด้วยการขว้างด้วยความสับสน ฉันชอบใช้การเปรียบเทียบกับระดับค่าเพื่ออธิบายสิ่งนี้เนื่องจากผู้คนมักจะคุ้นเคยกับมันมากกว่า
ตัวสร้างประเภทคือชนิดที่คุณสามารถใช้กับอาร์กิวเมนต์ชนิดเพื่อ "สร้าง" ชนิด
ตัวสร้างค่าเป็นค่าที่คุณสามารถนำไปใช้กับอาร์กิวเมนต์ค่าเพื่อ "สร้าง" ค่า
ตัวสร้างมูลค่ามักเรียกว่า "ฟังก์ชั่น" หรือ "เมธอด" "คอนสตรัคเตอร์" เหล่านี้ถูกกล่าวว่าเป็น "polymorphic" (เพราะพวกเขาสามารถใช้เพื่อสร้าง "สิ่ง" ของ "รูปร่าง" ที่แตกต่างกัน) หรือ "abstractions" (เนื่องจากพวกเขามีความเป็นนามธรรมมากกว่าสิ่งที่แตกต่างกันระหว่าง
ในบริบทของ abstraction / polymorphism คำสั่งแรกหมายถึง "การใช้ครั้งเดียว" ของ abstraction: คุณใช้นามธรรมมากกว่าหนึ่งครั้ง แต่ประเภทนั้นไม่สามารถทำให้เป็นนามธรรมได้ Java 5 generics เป็นลำดับแรก
การตีความลำดับแรกของการอธิบายลักษณะนามธรรมข้างต้นคือ:
ตัวสร้างประเภทเป็นประเภทที่คุณสามารถใช้กับอาร์กิวเมนต์ประเภทที่เหมาะสมเพื่อ "สร้าง" ประเภทที่เหมาะสม
ตัวสร้างค่าเป็นค่าที่คุณสามารถใช้กับอาร์กิวเมนต์ค่าที่เหมาะสมเพื่อ "สร้าง" ค่าที่เหมาะสม
เพื่อเน้นว่าไม่มีสิ่งที่เกี่ยวข้อง (ฉันเดาว่าคุณสามารถเรียกสิ่งนี้ว่า "zero-order" แต่ฉันไม่เคยเห็นสิ่งนี้มาใช้เลย) เช่นค่า1
หรือประเภทString
เรามักจะพูดบางอย่างว่าเป็นค่าหรือประเภทที่ "เหมาะสม"
ค่าที่เหมาะสมคือ "ใช้งานได้ทันที" ในแง่ที่ว่ามันไม่ได้รอการโต้แย้ง (มันไม่ได้เป็นนามธรรมเหนือพวกเขา) คิดว่ามันเป็นค่าที่คุณสามารถพิมพ์ / ตรวจสอบได้ง่าย ๆ (การทำให้ฟังก์ชั่นเป็นอนุกรมคือการโกง!)
ประเภทที่เหมาะสมคือประเภทที่จัดประเภทค่า (รวมถึงตัวสร้างค่า) ตัวสร้างประเภทจะไม่จัดประเภทค่าใด ๆ (ก่อนอื่นพวกเขาจำเป็นต้องนำไปใช้กับอาร์กิวเมนต์ประเภทที่ถูกต้อง ในการสร้างอินสแตนซ์ของชนิดจำเป็นต้องมี (แต่ไม่เพียงพอ) ว่าเป็นประเภทที่เหมาะสม (อาจเป็นคลาสนามธรรมหรือคลาสที่คุณไม่มีสิทธิ์เข้าถึง)
"ลำดับที่สูงกว่า" เป็นคำทั่วไปที่หมายถึงการใช้ polymorphism / abstraction ซ้ำ ๆ มันหมายถึงสิ่งเดียวกันสำหรับประเภทและค่า polymorphic เป็นนามธรรมสิ่งที่เป็นนามธรรมที่เป็นนามธรรมสูงกว่าสิ่งที่เป็นนามธรรมมากกว่าบางสิ่งบางอย่าง สำหรับประเภทคำว่า "ระดับสูง" เป็นรุ่นที่มีวัตถุประสงค์พิเศษของ "ลำดับที่สูงกว่า" ทั่วไป
ดังนั้นตัวละครของเราในเวอร์ชันที่สูงกว่าจะกลายเป็น:
ตัวสร้างประเภทคือชนิดที่คุณสามารถใช้กับอาร์กิวเมนต์ชนิด (ชนิดที่เหมาะสมหรือตัวสร้างชนิด) เพื่อ "สร้าง" ชนิดที่เหมาะสม (ตัวสร้าง)
ตัวสร้างค่าเป็นค่าที่คุณสามารถใช้กับอาร์กิวเมนต์ค่า (ค่าที่เหมาะสมหรือตัวสร้างค่า) เพื่อ "สร้าง" ค่าที่เหมาะสม (ตัวสร้าง)
ดังนั้น "ลำดับสูงกว่า" ก็หมายความว่าเมื่อคุณพูดว่า "abstracting over X" คุณหมายถึงมันจริงๆ! สิ่งX
ที่ถูกทำให้เป็นนามธรรมมากกว่าจะไม่สูญเสีย "สิทธิในการเป็นนามธรรม" ของตัวเอง: มันสามารถสรุปได้ทุกอย่างที่ต้องการ (โดยวิธีการที่ฉันใช้คำกริยา "นามธรรม" ที่นี่เพื่อหมายถึง: ออกจากสิ่งที่ไม่จำเป็นสำหรับการกำหนดค่าหรือประเภทเพื่อที่จะสามารถแตกต่างกัน / ให้โดยผู้ใช้นามธรรมเป็นอาร์กิวเมนต์ .)
นี่คือตัวอย่างบางส่วน (ได้รับแรงบันดาลใจจากคำถามของ Lutz ทางอีเมล) เกี่ยวกับค่าและประเภทที่เหมาะสมลำดับแรกและสูงกว่า:
proper first-order higher-order
values 10 (x: Int) => x (f: (Int => Int)) => f(10)
types (classes) String List Functor
types String ({type λ[x] = x})#λ ({type λ[F[x]] = F[String]})#λ
ที่คลาสที่ใช้ถูกกำหนดเป็น:
class String
class List[T]
class Functor[F[_]]
เพื่อหลีกเลี่ยงการอ้อมผ่านการกำหนดคลาสคุณจำเป็นต้องแสดงฟังก์ชันชนิดไม่ระบุชื่อซึ่งไม่สามารถแสดงได้โดยตรงใน Scala แต่คุณสามารถใช้ประเภทโครงสร้างโดยไม่มีค่าใช้จ่ายทางไวยากรณ์มากเกินไป (the- #λ
style เกิดจากhttps://stackoverflow.com / users / 160378 / retronym afaik):
ใน Scala เวอร์ชันสมมุติฐานในอนาคตที่รองรับฟังก์ชั่นประเภทไม่ระบุตัวตนคุณสามารถตัดบรรทัดสุดท้ายจากตัวอย่างเป็น:
types (informally) String [x] => x [F[x]] => F[String]) // I repeat, this is not valid Scala, and might never be
(ในบันทึกส่วนตัวฉันเสียใจที่ได้พูดคุยเกี่ยวกับ "ประเภทที่สูงกว่าประเภท" พวกเขาเป็นเพียงประเภทหลังจากทั้งหมด! เมื่อคุณต้องการอย่างชัดเจนฉันขอแนะนำให้พูดสิ่งต่าง ๆ เช่น "พารามิเตอร์ตัวสร้างประเภท", "สมาชิกตัวสร้างประเภท" หรือ "นามแฝงตัวสร้างประเภท" เพื่อเน้นว่าคุณไม่ได้พูดถึงประเภทที่เหมาะสมเท่านั้น)
ป.ล. : จะทำให้เรื่องยุ่งยากมากขึ้น "polymorphic" นั้นมีความกำกวมในวิธีที่แตกต่างกันเนื่องจากบางครั้งชนิด polymorphic หมายถึงประเภทที่มีปริมาณในระดับสากลเช่นForall T, T => T
ซึ่งเป็นประเภทที่เหมาะสมเนื่องจากมันจำแนกค่า polymorphic (ใน Scala ค่านี้ เขียนเป็นประเภทโครงสร้าง{def apply[T](x: T): T = x}
)