Modules
Edit on GitHubLarger projects are best maintained when the project’s code is broken up into smaller units. In Grain, we can utilize modules to accomplish this goal. A module can be used to organize a set of code together and make certain portions of itself available to other modules for usage. Each Grain file in your project is itself a module, and modules can be further split into submodules.
Providing From a Module
When we want to make something within a module available for another module to use, we can provide
it. Say we write this code in a file a.gr
:
1 | module ModuleA |
Now, we can make use of the values provided from this module in a different module: Say we write this code in a new file in the same directory as a.gr
above:
As you can see, our new module can use the function we defined in our first module!
Submodules
We can create modules within modules as well! This can be used to further split code within a file (or to further split a submodule in a file).
Providing after Declaration
It is also possible to provide an item from a module after it was initially declared using provide { ... }
syntax.
Standard Library include
s
We can use a standard library module by including the name of the module. Unlike including relative paths to code we’ve written, we can exclude the .gr
file extension.
The name in quotes, "list"
, is the path to the module. Grain knows how to find all of the modules in the standard library, so we can just say "list"
without having to determine where the standard library files exist on our computer.
Referencing Modules with a Different Name
As you’ve seen so far, we can include a module in another module by using include ...
syntax with the name of the module following include
. However, if we want to refer to that module using a different name we have the ability to do so:
Bring Values from a Module into Scope
Individual items in a module can be brought into scope with the use
keyword and placing the desired items in curly braces. Similar to with the provide { ... }
syntax, we need to prefix types with type
and modules with module
. as
can also be used to change the name an item from the target module is brought into scope as
Bringing All Values into Scope
If we want to bring all of the contents of another module into scope in our program, we can use an asterisk.