Monthly Archives: June 2020

Getting Started with Cabal

Cabal is the Haskell package and build tool.

The following are a few of the “getting started” commands.

What version do you have of Cabal?

Run the following

cabal --version

Check for updates to Cabal

You can check

cabal new-install Cabal cabal-install

Check for package updates

This command will pull the latest package list from hackage.haskell.org

cabal update

Creating a new project

We can create a new Haskell project using

cabal init

This will create a Main.hs, Setup.hs and a .cabal file for your configurations. We can then edit the .cabal file or we can run the interactive version and supply details using

cabal init -i

Building our project

We can build our project by simply using

cabal build

Running our project

To run (or build and run)

cabal run

Cleaning our project

cabal clean

Running the ghci repl

You can run ghci by simply typing

ghci

Or you can run the ghci that’s available via cabal using

cabal repl

Adding a library

We can download and install package from The Haskell Package Repository using the command

cabal install --lib QuickCheck HUnit

This installs the packages QuickCheck and HUnit from the package repository. The –lib is used for packages which do not contain an executable (i.e. a library package). We can also install .gz packages by specifying a file location or URL.

Packages are then stored on Windows in

%USERPROFILE%\AppData\Roaming\cabal\store\ghc-8.10.1

References

Welcome to the Cabal User Guide

The Haskell repl – basic commands

Haskell’s repl can be run use ghci or cabal repl. The repl using : to prefix commands, so for example :? will list the help.

I’m not going to go through all commands, but just the one’s I’ve been using regularly, check out Cabal for the full list of commands and features.

Quitting the repl

Let’s start by looking at how to quitting the repl (gracefully)

Prelude> :q

Writing code

Obviously we want to be able to execute code in the repl, in such cases we write code such as

x = 1 + 2
-- press enter
x
-- press enter

The output from this will obviously be 3.

To handle multi line input we create a block using :{ and :}, for example

:{
data Expr = Lit Integer |
            Div Expr Expr
:}

Don’t forget indention is required!

Loading existing code

In some cases we might want to load existing code into the repl, such a data definitions etc. Let’s say we have a Main.hs then run

:load Main

Display information

Assuming we added the Expr data type, to the repl, we might want to show the definition at some point, just use

:i Expr

Showing the type of an expression

Let’s assume we have something like the following in a module

eval :: Expr -> Integer

We can use the following to return the type (obviously in this instance we should see the above, but this command can ofcourse be executed against types where we want to find the type annotations/decalaractions

:t Expr

Now try

:t print

and you’ll see the following

print :: Show a => a -> IO ()

References

Using GHCi
Cabal User Guide

How to yarn link when the package is not published?

In the previous post we looked at using yarn link to work on development of a package whilst using it within our application (or other package).

There’s a problem. This only works if you’ve previously published the package to an npm compatible repository because when you run yarn in your application, it’ll see the dependency of your package and try to get it from the remote repository.

Note: this in not an issue if the package was published it’s only an issue for unpublished packages.

What we can do is change the dependency from using a version number to essentially use a local path. For example, let’s assume we have the following in our packages.json

"dependencies": {
   "@namespace/package-name": "1.0.0"
}

As stated, running yarn will result in and error no such package available. Changing this line to

"dependencies": {
   "@namespace/package-name": "link:../dev/package-name"
}

In other words, link: followed by the path to our package under development, then all will work, running yarn will no longer fail with the no such package available error.

You also needn’t run the link commands on the package or application to create a symbolic link if you use this syntax, just remember to change it back to the version number once the package is published.

yarn link

Yarn’s link functionality is really useful when developing a package and wanting to use it in your application whilst the package is in development.

Let’s assume you’ve created a package, for the sake of having an example, let’s assume it’s a cool new radio button control. You’ve created it and pushed to npm and all’s great but then you want to make some changes.

You don’t want to make those changes and push them to npm so that you can test them, yes you could take the code from the package etc. or use Yalc.

Or we can use yarn link.

In the package you’re editing, simply run

yarn link

this will result in the following command being available to run in the application using the package

yarn link "@namespace/package-name"

Note: obviously remove the namespace if non is used and replace package-name with the name of the package to link.

After you execute the above command and if you’re using Visual Code’s look at the explorer window, in the node_modules of the application using the package you’ll find the @namespace/package-name with a little symbolic link icon.

If you wish to unlink then, from your application use

yarn unlink "@namespace/package-name"

and from the package itself

yarn ulink