İşte iki buçuk farklı şey yapan kendi operatörlerinizi tanımlamanıza izin veren üç dil ! Haskell ve Coq her ikisi de bu tür maskaralıklara izin vermiyor - ama farklı olarak - Agda bu tür ilişkilerin karıştırılmasına izin veriyor.
İlk olarak, Haskell'de bunu yapmanıza izin verilmiyor. Kendi operatörlerinizi tanımlayabilir ve onlara önceliklerinizi (0-9 arasında) ve istediğiniz birliği verebilirsiniz. Ancak, Haskell Raporu , ortaklıkları karıştırmanıza izin vermez :
Bir sözdizimi hatasını önlemek için aynı önceliğe sahip art arda saydam olmayan işleçlerin hem sol hem de sağ ilişkilendirici olması gerekir. [Haskell 2010 Raporu, Böl. 3]
Dolayısıyla, GHC'de , aynı öncelik düzeyinde bir sol çağrışım ( infixl
) operatörü <@
ve sağ çağrışımsal operatör tanımlarsak @>
- 0 diyelim - o zaman değerlendirme x <@ y @> z
hatayı verir
Öncelik ayrıştırma hatası , aynı infix ifadesinde
' <@
' [ infixl 0
] ve ' @>
' [ infixr 0
] öğelerini karıştıramaz
(Aslında, bir operatörün bir infix olduğunu, ancak ilişkisel ==
olmadığını x == y == z
, yani sözdizimi hatası olduğunu bildirebilirsiniz !)
Öte yandan, bağımlı olarak yazılan dil / teorem kanıtlayıcı Agda (kuşkusuz, daha az ana akımdır ) var. Agda, mixfix operatörlerini destekleyen, bildiğim herhangi bir dilin en biçimlendirilebilir sözdiziminin bazılarına sahiptir : standart kütüphane işlevi içerir
if_then_else_ : ∀ {a} {A : Set a} → Bool → A → A → A
arandığında yazılan
if b then t else f
alt çizgileri dolduran argümanlar ile! Bundan bahsediyorum çünkü bu inanılmaz esnek ayrıştırmayı desteklemesi gerektiği anlamına geliyor. Doğal olarak, (onun öncelik seviyeleri üzerinde keyfi doğal sayılar değişir ve tipik 0-100 olmasına rağmen) Agda da fixity bildirimleri vardır ve Agda yapar aynı öncelik ancak farklı fixities operatörlerine karıştırmak için izin verir. Bununla birlikte, bu konuda dokümantasyonda bilgi bulamıyorum, bu yüzden denemek zorunda kaldım.
Hadi bizim <@
ve @>
yukarıdan tekrar kullanalım . İki basit durumda,
x <@ y @> z
olarak ayrıştırma x <@ (y @> z)
; ve
x @> y <@ z
olarak ayrıştırma (x @> y) <@ z
.
Ben düşünüyorum Ne Agda yaptığı grup "sol birleştirici" ve "sağ çağrışımlı" parçalar halinde çizgisini ve - Ben yanlış şeyler düşünüyorum sürece - sağ ilişkisel yığın bitişik argümanlar kapma "öncelik" alır. Bu bize
a <@ b <@ c @> d @> e @> f <@ g
olarak ayrıştırma
(((a <@ b) <@ (c @> (d @> (e @> f)))) <@ g
veya
Ancak, deneylerime rağmen, ilk kez yazdığımda yanlış olduğunu tahmin ettim, bu da öğretici olabilir :-)
(Ve Agda, Haskell gibi, ayrıştırma hatalarını doğru bir şekilde veren ilişkisel olmayan işleçlere sahiptir, bu nedenle karışık ilişkilendirmelerin ayrıştırma hatasına neden olması da mümkündür.)
Son olarak, Agda'dan bile daha esnek bir sözdizimine sahip olan teorem kanıtlayıcı / bağımlı olarak yazılan dil Coq var , çünkü sözdizimi uzantıları aslında yeni sözdizimsel yapılar için spesifikasyonlar verilerek ve daha sonra bunları çekirdek dile yeniden yazarak (belirsiz makro benzeri) , Sanırım). Coq'ta, liste sözdizimi [1; 2; 3]
standart kitaplıktan isteğe bağlı bir içe aktarmadır. Yeni sözdizimleri değişkenleri bile bağlayabilir!
Bir kez daha, Coq'da, kendi infix operatörlerimizi tanımlayabilir ve onlara öncelik seviyeleri (çoğunlukla 0-99 arasında) ve ilişkilendirmeler verebiliriz. Bununla birlikte, Coq'ta, her öncelik seviyesinin sadece bir ilişkisi olabilir . Dolayısıyla <@
, sol çağrışım olarak tanımlayıp sonra @>
aynı düzeyde sağ çağrışım olarak tanımlamaya çalışırsak - örneğin, 50 -
Hata: Seviye 50 zaten sağ ilişkilendirici olarak ilan edildi, ancak şimdi sağ ilişkilendirici olması bekleniyor
Coq'taki çoğu operatör 10 ile bölünebilen seviyelerdedir; ilişkilendirilebilirlik sorunları yaşadım (bu düzey ilişkilendirmeler globaldir), genellikle düzeyi her iki yönde de (genellikle yukarı) birer birer çarptım.