mixfix-operators.lagda.rst 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. ..
  2. ::
  3. module language.mixfix-operators where
  4. data Bool : Set where
  5. true : Bool
  6. false : Bool
  7. data _≡_ {A : Set} : (a b : A) → Set where
  8. refl : {a : A} → a ≡ a
  9. infix 4 _≡_
  10. module M where
  11. postulate _∙_ : Bool → Bool → Bool
  12. .. _mixfix-operators:
  13. ****************
  14. Mixfix Operators
  15. ****************
  16. A type name, function name, or constructor name can comprise one or more name
  17. parts if we separate them with underscore characters ``_``, and the
  18. resulting name can be used as an operator. From left to right, each argument
  19. goes in the place of each underscore ``_``.
  20. For instance, we can join with underscores the name parts ``if``, ``then``,
  21. and ``else`` into a single name ``if_then_else_``. The application of the
  22. function name ``if_then_else_`` to some arguments named ``x``, ``y``, and ``z``
  23. can still be written as:
  24. * a standard application by using the full name ``if_then_else_ x y z``
  25. * an operator application by placing the arguments between the name parts
  26. ``if x then y else z``, leaving a space between arguments and part names
  27. * other *sections* of the full name, for instance leaving one or two underscores:
  28. * ``(if_then y else z) x``
  29. * ``(if x then_else z) y``
  30. * ``if x then y else_ z``
  31. * ``if x then_else_ y z``
  32. * ``if_then y else_ x z``
  33. * ``(if_then_else z) x y``
  34. Examples of type names, function names, and constructor names as mixfix
  35. operators:
  36. ::
  37. -- Example type name _⇒_
  38. _⇒_ : Bool → Bool → Bool
  39. true ⇒ b = b
  40. false ⇒ _ = true
  41. -- Example function name _and_
  42. _and_ : Bool → Bool → Bool
  43. true and x = x
  44. false and _ = false
  45. -- Example function name if_then_else_
  46. if_then_else_ : {A : Set} → Bool → A → A → A
  47. if true then x else y = x
  48. if false then x else y = y
  49. -- Example constructor name _∷_
  50. data List (A : Set) : Set where
  51. nil : List A
  52. _∷_ : A → List A → List A
  53. .. _precedence:
  54. Precedence
  55. ==========
  56. Consider the expression ``true and false ⇒ false``.
  57. Depending on which of ``_and_`` and ``_⇒_`` has more precedence,
  58. it can either be read as ``(false and true) ⇒ false = true``,
  59. or as ``false and (true ⇒ false) = true``.
  60. Each operator is associated to a precedence, which is a floating point number
  61. (can be negative and fractional!).
  62. The default precedence for an operator is 20.
  63. .. note::
  64. Please note that ``->`` is directly handled in the parser. As a result, the
  65. precedence of ``->`` is lower than any precedence you may declare with
  66. ``infixl`` and ``infixr``.
  67. If we give ``_and_`` more precedence than ``_⇒_``, then we will get the first result::
  68. infix 30 _and_
  69. -- infix 20 _⇒_ (default)
  70. p-and : {x y z : Bool} → x and y ⇒ z ≡ (x and y) ⇒ z
  71. p-and = refl
  72. e-and : false and true ⇒ false ≡ true
  73. e-and = refl
  74. But, if we declare a new operator ``_and’_``
  75. and give it less precedence than
  76. ``_⇒_``, then we will get the second result::
  77. _and’_ : Bool → Bool → Bool
  78. _and’_ = _and_
  79. infix 15 _and’_
  80. -- infix 20 _⇒_ (default)
  81. p-⇒ : {x y z : Bool} → x and’ y ⇒ z ≡ x and’ (y ⇒ z)
  82. p-⇒ = refl
  83. e-⇒ : false and’ true ⇒ false ≡ false
  84. e-⇒ = refl
  85. Fixities can be changed when importing with a ``renaming`` directive::
  86. open M using (_∙_)
  87. open M renaming (_∙_ to infixl 10 _*_)
  88. This code brings two instances of the operator ``_∙_`` in scope:
  89. * the first named ``_∙_`` and with its original fixity
  90. * the second named ``_*_`` and with the fixity changed to act like a
  91. left associative operator of precedence 10.
  92. .. _associativity:
  93. Associativity
  94. =============
  95. Consider the expression ``true ⇒ false ⇒ false``. Depending on whether ``_⇒_``
  96. associates to the left or to the right, it can be read as
  97. ``(false ⇒ true) ⇒ false = false``, or ``false ⇒ (true ⇒ false) = true``,
  98. respectively.
  99. If we declare an operator ``_⇒_`` as ``infixr``, it will associate to the right::
  100. infixr 20 _⇒_
  101. p-right : {x y z : Bool} → x ⇒ y ⇒ z ≡ x ⇒ (y ⇒ z)
  102. p-right = refl
  103. e-right : false ⇒ true ⇒ false ≡ true
  104. e-right = refl
  105. If we declare an operator ``_⇒’_`` as ``infixl``, it will associate to the left::
  106. infixl 20 _⇒’_
  107. _⇒’_ : Bool → Bool → Bool
  108. _⇒’_ = _⇒_
  109. p-left : {x y z : Bool} → x ⇒’ y ⇒’ z ≡ (x ⇒’ y) ⇒’ z
  110. p-left = refl
  111. e-left : false ⇒’ true ⇒’ false ≡ false
  112. e-left = refl
  113. Ambiguity and Scope
  114. ===================
  115. If you have not yet declared the fixity of an operator, Agda will
  116. complain if you try to use ambiguously:
  117. .. code-block:: agda
  118. e-ambiguous : Bool
  119. e-ambiguous = true ⇒ true ⇒ true
  120. .. code-block:: none
  121. Could not parse the application true ⇒ true ⇒ true
  122. Operators used in the grammar:
  123. ⇒ (infix operator, level 20)
  124. Fixity declarations may appear anywhere in a module that other
  125. declarations may appear. They then apply to the entire scope in which
  126. they appear (i.e. before and after, but not outside).
  127. Operators in telescopes
  128. =======================
  129. Agda does not yet support declaring the fixity of operators declared in
  130. telescopes, see `Issue #1235 <https://github.com/agda/agda/issues/1235>`.
  131. However, the following hack currently works:
  132. .. code-block:: agda
  133. module _ {A : Set} (_+_ : A → A → A) (let infixl 5 _+_; _+_ = _+_) where