以下に、独自の演算子を定義できる3つの言語を示します。これらの言語は2つ半の異なる処理を行います。HaskellとCoqはどちらもこれらの種類のシェナンガンを許可しませんが、異なる方法ですが、Agdaはこのような関連性の混合を許可します。
まず、Haskellでは、単にこれを行うことは許可されていません。 独自の演算子を定義して、優先順位(0〜9)および選択した結合性を与えることができます。 ただし、Haskellレポートでは、関連性の混在は許可されていません。
同じ優先順位を持つ連続した括弧なしの演算子は、構文エラーを回避するために、左または右の両方の連想演算子でなければなりません。[Haskell 2010レポート、Ch。3]
したがって、GHCでは、同じ優先順位レベル(たとえば0 infixl
)で左結合()演算子<@
と右結合演算子を定義すると、@>
評価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
引数にアンダースコアを記入してください!これは非常に柔軟な解析をサポートする必要があることを意味するため、これについて言及します。当然のことながら、(その優先レベルを超える任意の自然数の範囲で、通常は0〜100であるが)Agdaはまた、結合性宣言を持っている、とAgdaはありません同じ優先順位が異なるfixitiesのオペレータをミックスすることを許可します。ただし、ドキュメントでこれに関する情報を見つけることができないため、実験する必要がありました。
<@
と@>
を上から再利用しましょう。2つの単純なケースでは、
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
または
しかし、私の実験にもかかわらず、私が最初にそれを書いたときに間違ったことを推測しました。これは有益かもしれません:-)
(そして、HaskellのようなAgdaには、解析エラーを正しく与える非連想演算子があります。そのため、混合結合性が解析エラーを引き起こす可能性があります。)
最後に、定理証明/依存型言語Coqがあります。これは、Agdaよりもさらに柔軟な構文を持っています。これは、構文拡張が実際に新しい構文構造の仕様を指定し、コア言語(漠然とマクロのように書き換えることで実装されているためです) 、 私は考えます)。Coqでは、リスト構文[1; 2; 3]
は標準ライブラリからのオプションのインポートです。新しい構文でも変数をバインドできます!
繰り返しになりますが、Coqでは、独自の挿入演算子を定義し、それらに優先順位レベル(主に0〜99)と結合性を与えることができます。ただし、Coqでは、各優先レベルに設定できる結合性は1つのみです。したがって、<@
左結合@>
として定義してから、同じレベル(たとえば50)で右結合として定義しようとすると、
エラー:レベル50は既に左結合と宣言されていますが、現在は右結合と想定されています
Coqのほとんどの演算子は、10で割り切れるレベルにあります。アソシエティビティの問題がある場合(これらのレベルアソシエティビティはグローバルです)、通常、いずれかの方向(通常は上)にレベルを1つ上げました。