Skip to content

Commit 0f2e13e

Browse files
committed
add some documentation
1 parent e5301db commit 0f2e13e

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
2+
.. _binding:
3+
4+
*********
5+
Binding Application
6+
*********
7+
8+
Binding application allows to overload the syntax of function application to better express the
9+
semantics of dependent types. Take for example the mathematical notation for Sigma-types:
10+
:math:`\Sigma x \in \mathbb{N} . Fin\ x` it binds the variable ``x`` and makes it available in the
11+
scope after the dot. Another example is the mathematical notation for ``forall``:
12+
:math:`\forall x \in \mathbb{N} | p x` it states that for all values ``x`` in the set of natural
13+
number, the property ``p`` holds.
14+
15+
Without any additional syntactic help those two types are only expressible using a lambda:
16+
17+
.. code-block:: idris
18+
record Sigma (a : Type) (p : a -> Type) where
19+
fst : a
20+
snd : p fst
21+
22+
record Pi (a : Type) (p : a -> Type) where
23+
fn : (x : a) -> p x
24+
25+
sigmaExample : Sigma Nat (\n => Vect n Int)
26+
27+
piExample : Pi Nat (\n => Vect n Int)
28+
29+
30+
Ideally, instead of relying on a lambda, we would like to write something closer to the original
31+
mathematical notation, binding application allows the following syntax:
32+
33+
.. code-block:: idris
34+
sigmaExample' : Sigma (n : Nat) | Vect n Int
35+
36+
piExample' : Pi (n : Nat) | Vect n Int
37+
38+
Binding Types
39+
=============
40+
41+
There are two way to use the binding application, the most common one is to bind a type to a name. If
42+
we take our ``Sigma`` example again it means that we need to tell the compiler that the type
43+
constructor can be used with binding syntax. We do this by annotating the type declaration with
44+
the ``typebind`` keyword.
45+
46+
47+
.. code-block:: idris
48+
typebind
49+
record Sigma (a : Type) (p : a -> Type) where
50+
constructor MkSigma
51+
fst : a
52+
snd : p fst
53+
54+
55+
We can also annotate functions with the same keyword, for example the following alias is allowed:
56+
57+
.. code-block:: idris
58+
typebind
59+
Σ : (a : Type) -> (p : a -> Type) -> Type
60+
Σ = Sigma
61+
62+
In the implementation of this function we've used the ``Sigma`` type-constructor without any binding
63+
syntax. That is because marking something as binding does not stop them from using them with regular
64+
function application, for example the following is allowed:
65+
66+
.. code-block:: idris
67+
-- binding syntax
68+
s1 : Sigma (n : Nat) | Fin n
69+
s1 = ...
70+
71+
-- pointfree notation is allowed
72+
s2 : Sigma Nat Fin
73+
s2 = ...
74+
75+
s3 : (Nat -> Type) -> Type
76+
s3 = Sigma Nat -- partial application is allowed
77+
78+
79+
We've seen that you can annotate functions and type constructors, you can also annotate data-constructors. For example, to annotate a record constructor add the keyword before the `constructor` keyword:
80+
81+
.. code-block:: idris
82+
record Container where
83+
typebind
84+
constructor MkCont
85+
goal : Type
86+
solution : goal -> Type
87+
88+
ListCont : Container
89+
ListCont = MkCont (n : Nat) | Fin n
90+
91+
You can also annotate constructors for data:
92+
93+
.. code-block:: idris
94+
data Desc : Type where
95+
-- normal constructors
96+
One : Desc
97+
Ind : Desc -> Desc
98+
99+
-- binding data constructor
100+
typebind
101+
Sig : (s : Type) -> (s -> Desc) -> Desc
102+
103+
104+
Binding Arbitrary Values
105+
========================
106+
107+

0 commit comments

Comments
 (0)