มีภาษาโปรแกรมที่อนุญาตให้คุณตั้งค่าทางคณิตศาสตร์กับชนิดหรือไม่?


9

อยากรู้อยากเห็นมีภาษาที่ช่วยให้คุณสามารถตั้งค่าทางคณิตศาสตร์ในประเภทที่จะสร้างประเภทใหม่ได้หรือไม่ สิ่งที่ต้องการ:

interface A {
  void a();
  void b();
}

interface B {
  void b();
  void c();
}

interface C = A & B; // has b()
interface D = A | B; // has a(), b() and c()
interface E = (A & B) ^ B; // has c()

ฉันรู้ว่าในบางภาษาความคิดเหล่านี้สามารถแสดงได้ (เช่น Java มีList<Comparable & Serializable>ไว้สำหรับส่วนต่อประสานของอินเทอร์เฟซ) แต่ฉันไม่เคยได้ยินภาษาที่รองรับประเภทคณิตศาสตร์ ขอบคุณ!


7
กลไกดังกล่าวจะมีประโยชน์อย่างไร
Robert Harvey

4
รูปแบบที่ฉันเห็นเป็นจำนวนมากคืออินเทอร์เฟซที่ขยายส่วนต่อประสานอีกสองส่วนและไม่ได้เพิ่มอะไรเลย (เช่นCanWriteAndCompare extends Serializable, Comparable {}) และฉันคิดว่าจะพูดคุยเรื่องนี้อย่างไร
Haldean Brown

2
นอกจากนี้ฉันวิ่งเข้าไปในกรณีที่วันนี้ที่ฉันมีวิธีการที่สามารถใช้AหรือBมีสองการใช้งานที่มีลักษณะเหมือนกันทั้งหมด ในวิธีการที่ฉันเรียกวิธี polymorphic ที่สามารถใช้Aหรือ a Bดังนั้นการใช้งานเหมือนกัน แต่เนื่องจากฉันต้องใช้สองประเภทที่แตกต่างกันฉันต้องการการใช้งานที่สอง myMethod(A | B aOrB)นี้จะง่ายขึ้นถ้าฉันจะทำ
Haldean Brown


1
Orการดำเนินการสามารถจำลองได้โดยหลายมรดก
ผู้ใช้

คำตอบ:


4

แทนเจนต์ ( 0.3 สเป็ค ) ใช้สิ่งที่คล้ายกับสิ่งนี้ (ข้อจำกัดความรับผิดชอบ: นี่เป็นโครงการวิจัยเล็ก ๆ ของฉัน)

ปัจจุบันwithทำหน้าที่เป็นผู้ดำเนินการสหภาพการสร้างแบบจำลองมรดกแม้ว่าลัทธิปฏิบัตินิยมได้ทำให้มันไม่ได้สับเปลี่ยน เมื่อคุณแนะนำการใช้งานกับวิธีการต่างๆการรวมกลุ่มอย่างเข้มงวดของวิธีการที่มีชื่อเดียวกันนั้นมักจะไม่ใช่สิ่งที่คุณต้องการและเป็นไปไม่ได้ที่จะทำสิ่งใดถูก

intersectได้รับการสนับสนุนว่าแบบจำลองประเภทการอนุมานสำหรับบางอย่างเช่นfoo(T,T)ที่พารามิเตอร์แตกต่างกัน

การเติมเต็มมีความน่าสนใจ แต่นำไปสู่ประเภทบางส่วนที่ดูเหมือนไม่มีประโยชน์และ / หรือมีปัญหาในการรวมอย่างถูกต้อง - ดังนั้นจึงไม่รวม

ฉันรู้ว่ามีภาษาวิจัยอื่นอีกสองสามภาษาที่ฉันพบซึ่งมีลักษณะคล้ายกัน แต่ไม่สามารถจำได้ในขณะนี้ ปัญหาหลักคือสิ่งที่ไม่เป็นประโยชน์จริง ๆ โดยไม่ต้องพิมพ์โครงสร้างซึ่งไม่เป็นที่นิยมอย่างมากของตัวเอง อีกอย่างคือคุณต้องมีประเภท (ประเภทของประเภท) ในการจัดเก็บประเภทที่สร้างขึ้นหรืออื่น ๆ มันเป็นเพียงการจดชวเลขสำหรับสิ่งที่ไม่ได้เป็นสำนวนโดยเฉพาะอย่างยิ่งถ้าไม่มีความสามารถนั้น และนั่นก็ธรรมดาน้อยกว่าการพิมพ์เชิงโครงสร้าง

มันมีอคติและไม่มาก แต่ก็มี


5

ใช่ Ceylon เป็นภาษาที่มีสหภาพแบบเฉพาะกิจและสี่แยกตามที่อธิบายไว้ในบทนี้จากทัวร์ศรีลังกา:

http://ceylon-lang.org/documentation/1.0/tour/types/

มันน่าทึ่งกับจำนวนของสำนวนเท่ห์ที่คุณได้รับจากเรื่องนี้ นี่คือตัวอย่างหนึ่งที่น่าสนใจที่ผม blogged เมื่อเร็ว ๆ นี้ และนี่เป็นการนำเสนอสั้น ๆ ที่ผมได้อย่างรวดเร็วปัดสวะสำนวนหลายอย่างง่าย

ยิ่งไปกว่านั้นการรวมกลุ่ม / การแยกเป็น "การเชื่อมโยงที่หายไป" ซึ่งทำให้การอนุมานประเภททั่วไปใช้งานได้จริงในศรีลังกาเมื่อเทียบกับภาษาอื่น ๆ ซึ่งรวมชนิดย่อยและความหลากหลายแบบพารามิเตอร์

โปรดทราบว่ามีข้อ จำกัด สำหรับ "ประเภทคณิตศาสตร์" ตามที่คุณอธิบายไว้ ตัวอย่างเช่นคุณไม่สามารถมีตัวดำเนินการเสริมที่ตั้งค่าไว้ที่ระดับประเภทอย่างน้อยก็ไม่สามารถใช้งานได้

HTH


3

Scala สนับสนุนบางส่วน (ทางแยก แต่ไม่ใช่สหภาพแรงงาน) และภาษาใด ๆ ที่มี subtyping โครงสร้าง (ฉันคิดว่า OCaml เป็นตัวอย่าง) หรือระบบประเภทที่มีประสิทธิภาพเพียงพอที่จะเลียนแบบ (Haskell เป็นคลาสสิกหนึ่ง) จะมี "ประเภทชุดแบบเต็ม" "ความสามารถอย่างน้อยภายในส่วนของระบบพิมพ์ที่ยอมรับสิ่งต่าง ๆ (เกี่ยวข้องเมื่อมันถูกจำลอง ala HList / OOHaskell)

เนื่องจากฉันไม่รู้จัก OCaml เป็นอย่างดีฉันจะยกตัวอย่างของคุณที่ทำงานใน Scala:

trait A {
  def a(): Unit
  def b(): Unit
}

abstract class B { // just to prove it works with both traits and classes
  def b(): Unit
  def c(): Unit
}

type C = A with B
type D = { def b(): Unit } // not an exact translation, because unions aren't directly available
// type `E` is unrepresentable

เวอร์ชันสำหรับ Haskell จะขึ้นอยู่กับระบบบันทึกที่คุณใช้และน่าจะค่อนข้างเชยเพราะมันจะถูกเลียนแบบแทนที่จะสนับสนุนโดยกำเนิด

เท่าที่ฉันรู้ Ceylon มีทั้งการแยกและการรวมกลุ่มที่สร้างเป็นภาษาอย่างเต็มรูปแบบดังนั้นคุณสามารถสันนิษฐานได้ว่าการเข้ารหัสระดับ xor ในแง่ของสิ่งเหล่านั้น


1

Java รองรับส่วนต่อประสานประเภทอินเตอร์เฟซในบริบทบางอย่างแม้ว่าจะไม่ได้ไกลเท่าที่ฉันสามารถบอกได้ว่าอนุญาตให้สร้างตัวแปรของประเภทจุดแยก ประเภทการแยกอาจเข้ามาเล่นเช่นเมื่อใช้? :โอเปอเรเตอร์ หากตัวถูกดำเนินการตัวที่สองและตัวที่สามไปยังตัวดำเนินการนั้นเป็นส่วนต่อประสานที่ไม่เกี่ยวข้องซึ่งสืบทอดมาจากชุดของส่วนต่อประสานที่ซ้อนทับกันผลลัพธ์ของตัวดำเนินการจะเป็นชุดของส่วนต่อประสานที่ใช้ร่วมกัน


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.