7An Idris program consists of a collection of modules. Each module
8includes an optional ``module`` declaration giving the name of the
9module, a list of ``import`` statements giving the other modules which
10are to be imported, and a collection of declarations and definitions of
11types, interfaces and functions. For example, the listing below gives a
12module which defines a binary tree type ``BTree`` (in a file
21 | Node (BTree a) a (BTree a)
24 insert : Ord a => a -> BTree a -> BTree a
25 insert x Leaf = Node Leaf x Leaf
26 insert x (Node l v r) = if (x < v) then (Node (insert x l) v r)
27 else (Node l v (insert x r))
30 toList : BTree a -> List a
32 toList (Node l v r) = Btree.toList l ++ (v :: Btree.toList r)
35 toTree : Ord a => List a -> BTree a
37 toTree (x :: xs) = insert x (toTree xs)
39The modifiers ``export`` and ``public export`` say which names are visible
40from other modules. These are explained further below.
42Then, this gives a main program (in a file
43``bmain.idr``) which uses the ``Btree`` module to sort a list:
52 main = do let t = toTree [1,8,2,7,9,3]
53 print (Btree.toList t)
55The same names can be defined in multiple modules: names are *qualified* with
56the name of the module. The names defined in the ``Btree`` module are, in
66If names are otherwise unambiguous, there is no need to give the fully
67qualified name. Names can be disambiguated either by giving an explicit
68qualification, or according to their type.
70There is no formal link between the module name and its filename,
71although it is generally advisable to use the same name for each. An
72``import`` statement refers to a filename, using dots to separate
73directories. For example, ``import foo.bar`` would import the file
74``foo/bar.idr``, which would conventionally have the module declaration
75``module foo.bar``. The only requirement for module names is that the
76main module, with the ``main`` function, must be called
77``Main``—although its filename need not be ``Main.idr``.
82Idris allows for fine-grained control over the visibility of a
83module's contents. By default, all names defined in a module are kept
84private. This aides in specification of a minimal interface and for
85internal details to be left hidden. Idris allows for functions,
86types, and interfaces to be marked as: ``private``, ``export``, or
87``public export``. Their general meaning is as follows:
89- ``private`` meaning that it's not exported at all. This is the
92- ``export`` meaning that its top level type is exported.
94- ``public export`` meaning that the entire definition is exported.
97A further restriction in modifying the visibility is that definitions
98must not refer to anything within a lower level of visibility. For
99example, ``public export`` definitions cannot use private names, and
100``export`` types cannot use private names. This is to prevent private
101names leaking into a module's interface.
106- ``export`` the type is exported
108- ``public export`` the type and definition are exported, and the
109 definition can be used after it is imported. In other words, the
110 definition itself is considered part of the module's interface. The
111 long name ``public export`` is intended to make you think twice
116 Type synonyms in Idris are created by writing a function. When
117 setting the visibility for a module, it might be a good idea to
118 ``public export`` all type synonyms if they are to be used outside
119 the module. Otherwise, Idris won't know what the synonym is a
122Since ``public export`` means that a function's definition is exported,
123this effectively makes the function definition part of the module's API.
124Therefore, it's generally a good idea to avoid using ``public export`` for
125functions unless you really mean to export the full definition.
127Meaning for Data Types
128----------------------
130For data types, the meanings are:
132- ``export`` the type constructor is exported
134- ``public export`` the type constructor and data constructors are
138Meaning for Interfaces
139----------------------
141For interfaces, the meanings are:
143- ``export`` the interface name is exported
144- ``public export`` the interface name, method names and default
145 definitions are exported
148----------------------
150The default export mode can be changed with the ``%access``
151directive, for example:
161 | Node (BTree a) a (BTree a)
163 insert : Ord a => a -> BTree a -> BTree a
164 insert x Leaf = Node Leaf x Leaf
165 insert x (Node l v r) = if (x < v) then (Node (insert x l) v r)
166 else (Node l v (insert x r))
168 toList : BTree a -> List a
170 toList (Node l v r) = Btree.toList l ++ (v :: Btree.toList r)
172 toTree : Ord a => List a -> BTree a
174 toTree (x :: xs) = insert x (toTree xs)
176In this case, any function with no access modifier will be exported as
177``export``, rather than left ``private``.
179Propagating Inner Module API's
180-------------------------------
182Additionally, a module can re-export a module it has imported, by using
183the ``public`` modifier on an ``import``. For example:
192The module ``A`` will export the name ``a``, as well as any public or
193abstract names in module ``C``, but will not re-export anything from
199Defining a module also defines a namespace implicitly. However,
200namespaces can also be given *explicitly*. This is most useful if you
201wish to overload names within the same module:
212 test : String -> String
215This (admittedly contrived) module defines two functions with fully
216qualified names ``Foo.x.test`` and ``Foo.y.test``, which can be
217disambiguated by their types:
229Groups of functions can be parameterised over a number of arguments
230using a ``parameters`` declaration, for example:
234 parameters (x : Nat, y : Nat)
238The effect of a ``parameters`` block is to add the declared parameters
239to every function, type and data constructor within the
240block. Specifically, adding the parameters to the front of the
241argument list. Outside the block, the parameters must be given
242explicitly. The ``addAll`` function, when called from the REPL, will
243thus have the following type signature.
248 addAll : Nat -> Nat -> Nat -> Nat
250and the following definition.
254 addAll : (x : Nat) -> (y : Nat) -> (z : Nat) -> Nat
255 addAll x y z = x + y + z
257Parameters blocks can be nested, and can also include data declarations,
258in which case the parameters are added explicitly to all type and data
259constructors. They may also be dependent types with implicit arguments:
263 parameters (y : Nat, xs : Vect x a)
264 data Vects : Type -> Type where
265 MkVects : Vect y a -> Vects a
267 append : Vects a -> Vect (x + y) a
268 append (MkVects ys) = xs ++ ys
270To use ``Vects`` or ``append`` outside the block, we must also give the
271``xs`` and ``y`` arguments. Here, we can use placeholders for the values
272which can be inferred by the type checker:
276 *params> show (append _ _ (MkVects _ [1,2,3] [4,5,6]))
277 "[1, 2, 3, 4, 5, 6]" : String
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list