-
Notifications
You must be signed in to change notification settings - Fork 701
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ci skip]
- Loading branch information
Showing
2 changed files
with
160 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
Getting Started with Haskell and Cabal | ||
====================================== | ||
|
||
Installing the Haskell toolchain | ||
-------------------------------- | ||
|
||
To install the Haskell toolchain follow the `ghcup instructions | ||
<https://www.haskell.org/ghcup/>`__. | ||
|
||
|
||
Creating a new application | ||
-------------------------- | ||
|
||
Let's start by creating a simple Haskell application from scratch where we'll | ||
learn about a Haskell package's directory structure, how to run the executable, | ||
and how to add external dependencies. | ||
|
||
|
||
Initializing the application | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
Start by creating a ``myfirstapp`` directory to hold the project files: | ||
|
||
.. code-block:: console | ||
$ mkdir myfirstapp && cd myfirstapp | ||
Once you have an empty directory we can initialize our package: | ||
|
||
.. code-block:: console | ||
$ cabal init | ||
This will generate the following files: | ||
|
||
.. code-block:: console | ||
$ ls | ||
CHANGELOG.md | ||
Main.hs | ||
myfirstapp.cabal | ||
``Main.hs`` is where your package's code lives. By default ``cabal init`` | ||
creates an executable with the same name as the package ``myfirstapp`` in this | ||
case, you can instruct ``cabal init`` to generate just a library (with | ||
``--lib``) or both a library and executable with (``--libandexe``); for the full | ||
set of options see ``cabal init --help``. | ||
|
||
``myfirstapp.cabal`` is Cabal's metadata file which describes your package and | ||
its dependencies. We'll be updating this file in a little bit when we add an | ||
external dependency to our package. | ||
|
||
.. note:: By default the name of the current directory will be used for the | ||
package name, you can change this with ``-p <package-name>``. | ||
|
||
|
||
Running the application | ||
^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
As mentioned above, ``cabal init`` with no arguments generates a package with a | ||
single executable that prints ``"Hello, Haskell!"`` to the terminal. To run the | ||
executable enter the following command: | ||
|
||
``cabal run :myfirstapp`` | ||
|
||
You should see the following output in the terminal: | ||
|
||
.. code-block:: console | ||
$ cabal run :myfirstapp | ||
... | ||
Hello, Haskell! | ||
.. note:: The ``:`` prefix in ``:myfirstapp`` signifies that the the | ||
``myfirstapp`` target is part of the current package. | ||
|
||
Notice that we didn't need to run a `build` command before ``cabal run``, this | ||
is because ``cabal run`` first determines if the code needs to be re-built | ||
before running the executable. If you just want to build a target you can do so | ||
with ``cabal build``: | ||
|
||
``cabal build :myfirstapp`` | ||
|
||
|
||
Adding dependencies | ||
^^^^^^^^^^^^^^^^^^^ | ||
|
||
Next we'll add an external dependency to our application. The unit of | ||
shareability in the Haskell ecosystem is a `package`, the database of available | ||
Haskell packages is called `Hackage <https://hackage.haskell.org/>`__. | ||
|
||
In our application, we'll use a package called `haskell-say | ||
<https://hackage.haskell.org/package/haskell-say>`__ to print text to the | ||
terminal with some embellishment. | ||
|
||
.. TIP:: | ||
If you installed ``cabal`` a while ago but haven't used it recently you may | ||
need to update the package index, you can do this by running ``cabal | ||
update``. | ||
|
||
In our ``myfirstapp.cabal`` file we'll update the ``build-depends`` attribute of | ||
the ``executable myfirstapp`` section to include ``haskell-say``: | ||
|
||
.. code-block:: cabal | ||
executable myfirstapp | ||
main-is: Main.hs | ||
build-depends: | ||
base >=4.11 && <4.12, | ||
haskell-say ^>=1.0.0.0 | ||
.. NOTE:: | ||
``^>=1.0.0.0`` means use version 1.0.0.0 of the library or any more recent | ||
minor release with the same major version. | ||
|
||
Next we'll update ``Main.hs`` to use the ``HaskellSay`` library: | ||
|
||
.. code-block:: haskell | ||
module Main where | ||
import HaskellSay (haskellSay) | ||
main :: IO () | ||
main = | ||
haskellSay "Hello, Haskell! You're using a function from another package!" | ||
``import HaskellSay (haskellSay)`` brings the ``haskellSay`` function from the | ||
module named ``HaskellSay`` into scope. The ``HaskellSay`` module is defined in | ||
the ``haskell-say`` packages that we added a dependency on above. | ||
|
||
Now you can build and re-run your code to see the new output: | ||
|
||
.. code-block:: console | ||
$ cabal run | ||
________________________________________________________ | ||
/ \ | ||
| Hello, Haskell! You're using a function from another | | ||
| package! | | ||
\____ _____________________________________________/ | ||
\ / | ||
\ / | ||
\/ | ||
_____ _____ | ||
\ \ \ \ | ||
\ \ \ \ | ||
\ \ \ \ | ||
\ \ \ \ \-----------| | ||
\ \ \ \ \ | | ||
\ \ \ \ \---------| | ||
/ / / \ | ||
/ / / \ \-------| | ||
/ / / ^ \ \ | | ||
/ / / / \ \ \ ----| | ||
/ / / / \ \ | ||
/____/ /____/ \____\ | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters