1- Getting Started with Haskell and Cabal
2- ======================================
1+ Getting Started
2+ ===============
33
4- Installing the Haskell toolchain
5- --------------------------------
6-
7- To install the Haskell toolchain follow the `ghcup instructions
8- <https://www.haskell.org/ghcup/> `__.
4+ Installing Cabal
5+ ----------------
96
7+ The easiest and recommended way to install the ``cabal `` command-line tool
8+ on Linux, macOS, FreeBSD or Windows is through `ghcup <https://www.haskell.org/ghcup/ >`__.
9+ It installs the “Haskell toolchain”, which includes Cabal,
10+ the Haskell compiler `GHC <https://www.haskell.org/ghc/ >`__
11+ and optionally other useful Haskell tools.
1012
1113Creating a new application
1214--------------------------
1315
14- Let's start by creating a simple Haskell application from scratch where we'll
15- learn about a Haskell package's directory structure, how to run the executable,
16- and how to add external dependencies.
16+ We create a minimal Haskell application to get a quick overview
17+ of the ``cabal `` command-line tool:
1718
19+ 1. How to initialize a Haskell package.
20+ 2. How files are organized inside a package.
21+ 3. How to compile Haskell files and run a resulting executable.
22+ 4. How to manage external dependencies.
1823
19- Initializing the application
20- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+ Initializing an application
25+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
2126
22- Start by initialising our ``myfirstapp `` project, these instructions work in
23- unix shells and PowerShell (if you're on Windows).
27+ To initialize a new Haskell application, run
2428
2529.. code-block :: console
2630
27- $ cabal init myfirstapp -n
28-
29- .. note :: ``myfirstapp`` stands for the directory (or path) where the project
30- will reside in, if omitted, ``cabal init `` will do its proceedings
31- in the directory it's called in.
31+ $ cabal init myapp --non-interactive
3232
33- .. note :: ``-n`` stands for ``--non-interactive``, which means that cabal will try to guess
34- how to set up the project for you and use the default settings, which will serve us
35- well for the purpose of this tutorial.
36- When setting up your projects in the future, you will likely want to omit ``-n ``
37- and do just ``cabal init ``, so that cabal will interactively ask you
38- for the details on how the project should be set up
39- (while still offering reasonable defaults on every step).
40- Also, you can run ``cabal init --help `` to get more info on how ``cabal init `` can be used.
41-
42- This will generate the following files:
33+ in a terminal. This generates the following files in a new ``myapp `` directory:
4334
4435.. code-block :: console
4536
4637 $ tree
4738 .
48- └── myfirstapp
39+ └── myapp
4940 ├── app
5041 │ └── Main.hs
5142 ├── CHANGELOG.md
52- └── myfirstapp .cabal
43+ └── myapp .cabal
5344
54- `` app/Main.hs `` is where your package's code lives.
45+ The `` myapp.cabal `` file is a package description file, commonly referred to as a “Cabal file”:
5546
56- ``myfirstapp.cabal `` is Cabal's metadata file which describes your package,
57- how it is built and its dependencies. We'll be updating this file in a
58- little bit when we add an external dependency to our package.
47+ .. code-block :: cabal
5948
49+ cabal-version: 3.0
50+ name: myapp
51+ version: 0.1.0.0
52+ -- ...
6053
61- Running the application
62- ^^^^^^^^^^^^^^^^^^^^^^^
54+ executable myapp
55+ import: warnings
56+ main-is: Main.hs
57+ build-depends: base ^>=4.19.0.0
58+ hs-source-dirs: app
59+ default-language: Haskell2010
6360
64- When we ran ``cabal init myfirstapp -n `` above, it generated a package with a single
65- executable named same as the package (in this case ``myfirstapp ``) that prints
66- ``"Hello, Haskell!" `` to the terminal. To run the executable enter the project's
67- directory and run it, by inputting the following commands:
61+ It contains metadata (package name and version, author name, license, etc.) and sections
62+ to define package components. Components can be used to split large codebases into smaller,
63+ more managable building blocks.
64+ A component can be of one of several types (executable, library, etc.) and describes,
65+ among other things, the location of source files and its dependencies.
66+ The ``myapp.cabal `` file above defines a single component named ``myapp `` of the executable type.
67+ Inside the ``executable `` section, the ``build-depends `` field lists the dependencies of this component.
6868
69- .. code-block :: console
7069
71- cd myfirstapp
72- cabal run myfirstapp
70+ The ``app/Main.hs `` file is where your executable's code lives:
71+
72+ .. code-block :: haskell
7373
74- You should see the following output in the terminal:
74+ module Main where
75+
76+ main :: IO ()
77+ main = putStrLn "Hello, Haskell!"
78+
79+
80+ To run the executable, switch into the application directory with ``cd myapp `` and run
7581
7682.. code-block :: console
7783
78- $ cabal run myfirstapp
84+ $ cabal run myapp
7985 ...
8086 Hello, Haskell!
8187
82- Notice that we didn't need to run a `build ` command before we ran ``cabal run ``.
83- This is because ``cabal run `` automatically determines if the code needs to be (re)built
84- before running the executable.
85- If you just want to build a target without running it, you can do so with ``cabal build ``:
88+ This command automatically determines if the executable needs to be (re)built
89+ before running the executable. With only one executable component in the package,
90+ ``cabal run `` (without a component name) is smart enough to infer it, so the name can be omitted.
91+
92+ If you just want to build the executable without running it, run:
93+
94+ .. code-block :: console
8695
87- ``cabal build myfirstapp ``
96+ $ cabal build
97+ Resolving dependencies...
98+ ...
99+ Building executable 'myapp' for myapp-0.1.0.0..
100+ [1 of 1] Compiling Main ( app/Main.hs, /home/.../myapp/dist-newstyle/build/.../myapp-tmp/Main.o )
101+ Linking /home/.../myapp/dist-newstyle/build/.../myapp
88102
89103
90104 Adding dependencies
@@ -103,16 +117,16 @@ terminal with some embellishment.
103117 need to update the package index, you can do this by running ``cabal
104118 update ``.
105119
106- In our ``myfirstapp .cabal `` file we'll update the ``build-depends `` attribute of
107- the `` executable myfirstapp `` section to include ``haskell-say ``:
120+ In our ``myapp .cabal `` file, we will update the ``build-depends `` field of
121+ the executable section to include ``haskell-say ``:
108122
109123.. code-block :: cabal
110124
111- executable myfirstapp
125+ executable myapp
112126 import: warnings
113127 main-is: Main.hs
114128 build-depends:
115- base ^>=4.14.3 .0,
129+ base ^>=4.19.0 .0,
116130 haskell-say ^>=1.0.0.0
117131 hs-source-dirs: app
118132 default-language: Haskell2010
@@ -132,8 +146,7 @@ Next we'll update ``app/Main.hs`` to use the ``HaskellSay`` library:
132146 import HaskellSay (haskellSay)
133147
134148 main :: IO ()
135- main =
136- haskellSay "Hello, Haskell! You're using a function from another package!"
149+ main = haskellSay "Hello, Haskell!"
137150
138151 ``import HaskellSay (haskellSay) `` brings the ``haskellSay `` function from the
139152module named ``HaskellSay `` into scope. The ``HaskellSay `` module is defined in
@@ -143,11 +156,10 @@ Now you can build and re-run your code to see the new output:
143156
144157.. code-block :: console
145158
146- $ cabal run
159+ $ cabal run myapp
147160 ________________________________________________________
148161 / \
149- | Hello, Haskell! You're using a function from another |
150- | package! |
162+ | Hello, Haskell! |
151163 \____ _____________________________________________/
152164 \ /
153165 \ /
@@ -166,42 +178,47 @@ Now you can build and re-run your code to see the new output:
166178 / / / / \ \
167179 /____/ /____/ \____\
168180
169- Run a single-file Haskell script
170- --------------------------------
181+ Running a single-file Haskell script
182+ ------------------------------------
171183
172- Cabal also enables us to run single-file Haskell scripts
173- without creating a project directory or ``.cabal `` file.
174- The cabal directives are placed in the file within a comment.
184+ Cabal also supports running single-file Haskell scripts like
185+ the following file named ``myscript ``:
175186
176187.. code-block :: haskell
177-
188+
178189 #!/usr/bin/env cabal
179190 {- cabal:
180- build-depends: base, split
191+ build-depends:
192+ base ^>=4.19.0.0,
193+ haskell-say ^>=1.0.0.0
181194 -}
182195
183- import Data.List.Split (chunksOf )
196+ import HaskellSay (haskellSay )
184197
185198 main :: IO ()
186- main = getLine >>= print . chunksOf 3
199+ main = haskellSay "Hello, Haskell!"
187200
188- This can be run using ``cabal run myscript ``.
189- On Unix-like systems this can be run directly with execute permission.
201+ The necessary sections of a ``.cabal `` file are placed
202+ directly into the script as a comment.
203+
204+ Use the familiar ``cabal run `` command to execute this script:
190205
191206.. code-block :: console
192207
193208 $ cabal run myscript
194209
195- $ chmod +x myscript
196- $ ./myscript
197-
198- Project metadata can also be included:
210+ On Unix-like systems, a Haskell script starting with ``#!/usr/bin/env cabal ``, like the one above,
211+ can be run directly after setting the execute permission (+x):
199212
200- .. code-block :: haskell
213+ .. code-block :: console
201214
202- {- project:
203- with-compiler: ghc-8.10.7
204- -}
215+ $ chmod +x myscript
216+ $ ./myscript
217+ ________________________________________________________
218+ / \
219+ | Hello, Haskell! |
220+ \____ ____________________________________________/
221+ \ ... /
205222
206223 See more in the documentation for :ref: `cabal run `.
207224
0 commit comments