Skip to content

Commit

Permalink
Create "Getting started" tutorial.
Browse files Browse the repository at this point in the history
[ci skip]
  • Loading branch information
m-renaud committed Apr 7, 2020
1 parent d4ebb69 commit 5e6b7a8
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
161 changes: 161 additions & 0 deletions Cabal/doc/getting-started.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
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
.. TIP::
``^>=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!"
.. TIP::
``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! |
\____ _____________________________________________/
\ /
\ /
\/
_____ _____
\ \ \ \
\ \ \ \
\ \ \ \
\ \ \ \ \-----------|
\ \ \ \ \ |
\ \ \ \ \---------|
/ / / \
/ / / \ \-------|
/ / / ^ \ \ |
/ / / / \ \ \ ----|
/ / / / \ \
/____/ /____/ \____\
1 change: 1 addition & 0 deletions Cabal/doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Welcome to the Cabal User Guide
:maxdepth: 2
:numbered:

getting-started
intro
config-and-install
concepts-and-development
Expand Down

0 comments on commit 5e6b7a8

Please sign in to comment.