ต่อไปนี้เป็นสามภาษาที่ให้คุณกำหนดผู้ให้บริการของคุณเองซึ่งทำสองสิ่งครึ่งแตกต่างกัน ! Haskell และ Coq ทั้งคู่ไม่อนุญาตประเภทของ shenanigans - แต่ต่างกัน - ในขณะที่ Agda อนุญาตให้มีการผสมกันของความสัมพันธ์แบบนี้
ก่อนอื่นในHaskellคุณไม่ได้รับอนุญาตให้ทำเช่นนี้ คุณสามารถกำหนดผู้ประกอบการของคุณเองและให้ความสำคัญกับพวกเขา (จาก 0–9) และการเชื่อมโยงที่คุณเลือก อย่างไรก็ตามรายงาน Haskell ไม่อนุญาตให้คุณผสมสมาคม :
ตัวดำเนินการที่ไม่ถูกยึดติดติดต่อกันที่มีลำดับความสำคัญเท่ากันต้องเป็นตัวเชื่อมโยงซ้ายหรือขวาเพื่อหลีกเลี่ยงข้อผิดพลาดทางไวยากรณ์ [รายงาน Haskell 2010, Ch. 3]
ดังนั้นในGHCหากเรากำหนดinfixl
โอเปอเรเตอร์ซ้าย - สัมพันธ์ ( ) <@
และโอเปอเรเตอร์ขวา@>
ที่ระดับความสำคัญเท่ากัน - สมมุติว่า 0 - แล้วการประเมินx <@ y @> z
จะทำให้เกิดข้อผิดพลาด
ข้อผิดพลาดในการแยกวิเคราะห์ลำดับความสำคัญ
ไม่สามารถผสม ' <@
' [ infixl 0
] และ ' @>
' [ infixr 0
] ในนิพจน์มัดเดียวกัน
(อันที่จริงแล้วคุณยังสามารถประกาศโอเปอเรเตอร์ให้เป็นมัด แต่ไม่ใช่แบบเชื่อมโยง==
ได้ดังนั้นนั่นx == y == z
เป็นข้อผิดพลาดทางไวยากรณ์!)
ในทางกลับกันมีผู้แปลภาษา / ทฤษฎีบทที่พิมพ์ได้อย่างพึ่งพากันAgda (ซึ่งเป็นที่ยอมรับกันว่ามีความสำคัญน้อยกว่า) Agda มีไวยากรณ์ที่อ่อนบางที่สุดของภาษาใด ๆ ที่ฉันรู้จักสนับสนุนตัวดำเนินการmixfix : ไลบรารีมาตรฐานมีฟังก์ชัน
if_then_else_ : ∀ {a} {A : Set a} → Bool → A → A → A
ซึ่งเมื่อมีการเรียกถูกเขียน
if b then t else f
ด้วยข้อโต้แย้งที่กรอกในขีดล่าง! ฉันพูดถึงสิ่งนี้เพราะนี่หมายความว่ามันต้องรองรับการแยกวิเคราะห์ที่ยืดหยุ่นอย่างไม่น่าเชื่อ โดยธรรมชาติแล้ว Agda ยังมีการประกาศ fixity (แม้ว่าระดับความสำคัญของมันจะอยู่เหนือตัวเลขธรรมชาติโดยพลการและอยู่ในช่วง 0-100) และ Agda จะอนุญาตให้คุณผสมตัวดำเนินการที่มีความสำคัญเหมือนกัน แต่ต่างกัน อย่างไรก็ตามฉันไม่สามารถค้นหาข้อมูลเกี่ยวกับสิ่งนี้ได้ในเอกสารดังนั้นฉันจึงต้องทำการทดสอบ
ลองนำมาใช้ใหม่ของเรา<@
และ@>
จากข้างต้น ในสองกรณีง่าย ๆ เรามี
x <@ y @> z
แยกเป็นx <@ (y @> z)
; และ
x @> y <@ z
(x @> y) <@ z
แยกเป็น
ฉันคิดว่าสิ่งที่ Agda ทำคือจัดกลุ่มบรรทัดเป็น "การเชื่อมโยงด้านซ้าย" และ "การเชื่อมโยงทางด้านขวา" และ - ถ้าฉันกำลังคิดเกี่ยวกับสิ่งผิดปกติ - การเชื่อมโยงกลุ่มด้านขวาได้รับ "ลำดับความสำคัญ" นั่นทำให้เรา
a <@ b <@ c @> d @> e @> f <@ g
การแยกเป็น
(((a <@ b) <@ (c @> (d @> (e @> f)))) <@ g
หรือ
อย่างไรก็ตามแม้จะมีการทดลองของฉันฉันเดาผิดครั้งแรกที่ฉันเขียนออกมาซึ่งอาจเป็นคำแนะนำ :-)
(และ Agda เช่น Haskell มีตัวดำเนินการที่ไม่เชื่อมโยงซึ่งให้ข้อผิดพลาดในการแยกวิเคราะห์อย่างถูกต้องดังนั้นจึงเป็นไปได้ที่การรวมกลุ่มแบบผสมจะทำให้เกิดข้อผิดพลาดในการแยกวิเคราะห์ด้วย)
ในที่สุดก็มีCoqภาษาที่ใช้ทฤษฎีบท / ผู้พึ่งพาอาศัยซึ่งมีไวยากรณ์ที่ยืดหยุ่นมากกว่า Agda เนื่องจากส่วนขยายไวยากรณ์นั้นถูกนำไปใช้จริงโดยการให้ข้อกำหนดสำหรับโครงสร้างไวยากรณ์ใหม่แล้วเขียนใหม่เป็นภาษาแกนกลาง ฉันคิดว่า) ใน Coq ไวยากรณ์ของรายการ[1; 2; 3]
เป็นการอิมพอร์ตทางเลือกจากไลบรารีมาตรฐาน ไวยากรณ์ใหม่สามารถผูกตัวแปรได้!
อีกครั้งใน Coq เราสามารถกำหนดตัวดำเนินการมัดของเราเองและกำหนดระดับความสำคัญ (ตั้งแต่ 0–99 ส่วนใหญ่) และการเชื่อมโยง อย่างไรก็ตามใน Coq แต่ละระดับความสำคัญจะมีหนึ่งการเชื่อมโยงเท่านั้น ดังนั้นถ้าเรานิยาม<@
ว่าเป็นความสัมพันธ์ด้านซ้ายแล้วลองนิยาม@>
ความสัมพันธ์ด้านขวาในระดับเดียวกัน - พูดว่า 50 - เราจะได้
ข้อผิดพลาด: ระดับ 50 ได้รับการประกาศว่าเชื่อมโยงกันแล้วขณะนี้คาดว่าจะมีการเชื่อมโยงที่ถูกต้อง
ตัวดำเนินการส่วนใหญ่ใน Coq อยู่ในระดับที่หารด้วย 10 หากฉันมีปัญหาการเชื่อมโยง (การเชื่อมโยงระดับเหล่านี้เป็นระดับโลก) ฉันมักจะชนระดับโดยหนึ่งในทิศทางใดทิศทางหนึ่ง (มักจะขึ้น)