다음은 두 가지 다른 작업 을 수행하는 고유 한 연산자를 정의 할 수있는 세 가지 언어입니다 . Haskell과 Coq는 이러한 종류의 shenanigan을 허용하지 않지만 Agda는 이러한 종류의 연관성을 혼합 할 수 있습니다.
첫째, Haskell 에서는 단순히 이것을 할 수 없습니다. 자신의 연산자를 정의하고 우선 순위 (0-9)와 선택한 연관성을 제공 할 수 있습니다. 그러나 Haskell Report에서는 연관성을 혼합 할 수 없습니다 .
구문 우선 순위가 동일한 연속적인 괄호로 묶지 않은 연산자는 왼쪽 또는 오른쪽으로 연관되어 있어야합니다. [Haskell 2010 보고서, Ch. 삼]
따라서 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는 고 정성 선언도 가지고 있습니다 (우선 순위 수준은 임의의 자연수보다 범위가 넓지 만 일반적으로 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
또는
그러나 내 실험에도 불구하고 처음으로 그것을 쓸 때 잘못된 것으로 추측했습니다.
또한 Haskell과 같은 Agda에는 비 연관 연산자가있어 구문 분석 오류가 올바르게 발생하므로 혼합 된 연관성이 구문 분석 오류도 발생할 수 있습니다.
마지막으로 정리 증명 / 종속 형 언어 Coq 가 있는데, 구문 확장은 실제로 새로운 구문 구조에 대한 사양을 제공하고 핵심 언어 (거의 매크로와 유사)로 다시 작성함으로써 Agda보다 훨씬 유연한 구문을 가지고 있습니다. , 나는 가정한다). Coq에서 목록 구문 [1; 2; 3]
은 표준 라이브러리에서 선택적으로 가져옵니다. 새로운 구문은 변수를 바인딩 할 수도 있습니다!
다시 한번, Coq에서 우리는 우리 자신의 접두사 연산자를 정의하고 그들에게 우선 순위 수준 (주로 0 ~ 99)과 연관성을 부여 할 수 있습니다. 그러나 Coq에서 각 우선 순위 레벨은 하나의 연관성을 가질 수 있습니다 . 따라서 <@
왼쪽 연관으로 정의한 다음 @>
같은 수준 (예 : 50)에서 오른쪽 연관 으로 정의하려고 하면
오류 : 레벨 50은 이미 왼쪽 연관으로 선언되었지만 이제 오른쪽 연관이어야합니다.
Coq의 대부분의 연산자는 10으로 나눌 수있는 레벨에 있습니다. 연관성 문제가있는 경우 (이러한 수준의 연관성에 문제가있는 경우) 일반적으로 어느 방향 으로든 (일반적으로 위) 한 단계 씩 수준을 올렸습니다.