DEV Community

loading...

Haskell Stack and Package Management

muttsuri profile image Muttsuri ・1 min read

Backstory:

So I know the somewhat very basics of haskell, and for a small program that I wanted to do I found a function in a library (the function was chunksOf form Data.List.Split, which was it's own confusing thing since for the looks of it the package name is split).
So I tried to look for a package manager, which lead me to stack. Now I tried to work with it but I don't want to build a massive project, I just want to experiment around a bit.

Confusion:

  • I do not understand the whole project structure (there is a lot of indirection and I can't tell even to which file I should be writing my code, it's a small thing I only want one file and one function from one lib).
  • Why is there not a simple package installer alternative, I feel the tool is getting in my way more than it's helping.
  • I find that this is more of a general haskell thing but I do agree that although it's hard documentation is good the soft one is lacking and I think it's what I'm feeling now. # TL;DR: I don't understand stack

PS: Sorry if this is too long this is my first post, I'm not sure how this works

Discussion (2)

pic
Editor guide
Collapse
gillchristian profile image
Christian Gill • Edited

EDIT: I just see you posted this a while ago. So you most probably figured things out by now πŸ˜…

Hi :)

Disclaimer #1: I'm not good at #explainlikeimfive but I'll give it a try.

Disclaimer #2: I'm not a an expert on stack just basically use it for the same reasons as you mention.

the function was chunksOf form Data.List.Split, which was it's own confusing thing since for the looks of it the package name is split

That's indeed confusing at first. Haskell modules follow (most of the time) a convention for the names. Eg. since the split package contains functions for splitting lists it defines the module Data.List.Split. A package might define many modules. To learn more about modules check out the first and last sections here.

I tried to work with it but I don't want to build a massive project, I just want to experiment around a bit

There are templates for creating projects with Stack, maybe you can find one with the bare minimum. The default one indeed looks like there's a lot going on, but once you are familiar with it you'll be fine.

I do not understand the whole project structure

Another thing that is confusing at first πŸ˜… But bare with me, it'll make sense. Stack creates sandboxed projects, in other words your project will have all the dependencies vendored to it and even it's own version of the compiler (this way different projects can have different dependencies and compiler versions). There are ways to install dependencies globally and ignore stack but eventually that becomes a problem because things won't work with each other.

I assume you installed stack already. To create a project with the default template you can run:

$ stack new my-project

That might take a bit of time to complete. It downloads a version of the compiler (if you don't have it already) for the project and sets up all the directories/files. Which should look something like this:

$ tree my-project
my-project
β”œβ”€β”€ ChangeLog.md
β”œβ”€β”€ LICENSE
β”œβ”€β”€ README.md
β”œβ”€β”€ Setup.hs
β”œβ”€β”€ app
β”‚Β Β  └── Main.hs
β”œβ”€β”€ my-project.cabal
β”œβ”€β”€ package.yaml
β”œβ”€β”€ src
β”‚Β Β  └── Lib.hs
β”œβ”€β”€ stack.yaml
└── test
    └── Spec.hs

You can ignore most of it. There are only a few files you'll care about. But don't remove them, some are still needed by stack.

These are the ones you'll be using now.

$ tree my-project
my-project
β”œβ”€β”€ app
β”‚Β Β  └── Main.hs
β”œβ”€β”€ package.yaml
β”œβ”€β”€ src
 Β Β  └── Lib.hs

package.yml

Here you configure the dependencies, modules, and a bunch of other things like default compiler options. For now the only thing you have to do is add the split package so Stack can download it. It will look something like this:

dependencies:
- base >= 4.7 && < 5
- split

Most of the time the version isn't needed, Stack knows which one is the right one.

You can ignore the rest inside package.yml for now. But if you want, feel free to play around and see how things break and what you can do with it.

After you add a package in dependencies you'd need to run either stack build, stack run or stack ghci. Stack will figure out there's a new dependency and download it.

IMPORTANT: don't run stack install split. That will install the package globally. But what you want is have it locally in your project.

app/Main.hs

This is the file that will produce the executable program.

Here you define the main :: IO () function that runs when you execute the program (like C++'s main). Stack already defined it for you. If you want, you can ignore what's in src/ and write all your code in this file.

src/Lib.hs

This is the library code. Stack will treat any file inside src/ as a module.

Module names need to match the file path/name. So src/Lib.hs defines the Lib module. Which can be imported in app/Main.hs. Stack takes care of that.

Normally the src/ directory is where you'd write your code and have the bare minimum in app/Main.hs to run your program.

Useful commands

There are a few Stack commands that are useful at first.

$ stack ghci

This runs the REPL. Stack takes care of importing your modules here, so you can for example call main directly.

Also as I mentioned, running this command will first install the new dependencies that were added to package.yml. If you add one while the REPL is already running you'll have to run the REPL again.

$ stack run

This will compile and execute your program. In other words run the main function from app/Main.hs.

Also installs dependencies before compiling.

$ stack build

In case you only want to compile run that one ☝️

$ stack install .

If you want to have your project available globally as a executable you can install it.

$ stack help

There's a lot of information about the Stack CLI there. Might also be useful.


I hope that was useful :)

Feel free to join the Functional Programming Slack. There's a channel for those of us that are learning Haskell (#haskell-beginners), you can ask questions like this one there. People is quite welcoming and will help you :)

Also, here are a few links that will help on getting stared with Stack:

And make sure to check the Stack documentation as well.

Happy and safe coding πŸŽ‰

Collapse
muttsuri profile image
Muttsuri Author

Actually I hadn't, I don't have experience with build tools like stack. I'm familiar with npm so the logic of having to compile before the tool downloads my packages is somewhat foreign to me.
Also my experience with app templates is also lacking. So finally having some understanding of the directory structure helps.
This comment helps me a lot thank you very much. πŸ˜„