Files
Lee Hanken 7c8efd2228 Initial commit: HPR Knowledge Base MCP Server
- MCP server with stdio transport for local use
- Search episodes, transcripts, hosts, and series
- 4,511 episodes with metadata and transcripts
- Data loader with in-memory JSON storage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-26 10:54:13 +00:00

246 lines
15 KiB
Plaintext

Episode: 3562
Title: HPR3562: Creating a new project with Haskell and Stack
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr3562/hpr3562.mp3
Transcribed: 2025-10-25 01:26:04
---
This is Hacker Public Radio Episode 3562 for Tuesday, the 29th of March 2022.
Today's show is entitled, Creating a New Project with Haskell and Stack.
It is part of the series Haskell.
It is hosted by Tukuturo Toe and is about 21 minutes long.
It carries a clean flag.
The summary is Tukuturo explains how to create a new Haskell project and build it.
Hello, this is Tula Turto and you are listening to The Hacker Public Radio.
Today's episode is about how to set up a new Haskell project.
As an example, we are going to write a tiny card game.
This episode won't contain all the code for the card game because it will take...
The episode will be just so long, but we'll get started today and continue on later on.
So, today we'll set up a project.
So, we are going to use Stack and Stack is a cross-platform program for developing Haskell projects.
There's a link into the show notes, leading to the Stack homepage.
So, what does Stack do?
It can, among other things, it can install KHE.
That's the Glasgow Haskell compiler automatically and in an isolated location.
So, if you are developing multiple projects that uses different versions of the KHE,
Stack will help you to manage that situation.
It will also install the packages that your project needs.
Again, in an isolated location, and it will build your project, test your project,
and benchmark your project.
This benchmarking part is actually something that I haven't done yet.
But, all data previously mentioned, yes.
So, our game will be called at the resurrection, it will be a turn-based card game.
And, it will run in a console.
So, don't expect any science graphics.
We want to write it in a console as a text mode to give things as simple as possible.
Because, if you are writing your first Haskell game, it is a really good idea,
not to start with something huge, but something small,
manageable that you can finish in a couple of weeks or in one or two.
So, our game is called at Residention.
I will go through rules, a group later, but the idea is that you have a deck of cards,
you flip them one by one, and there is a special event that your character has to be laid.
And, your character will have some items and stats that will help them to overcome the obstacles.
But, first, we need a project, and after installing the stack,
I'm not going to throw that, because that is a platform dependent and that might change.
So, if you are installing a stack, please refer to the stack home page for the instruction for that.
But, now that we have installed it, we are going to open a new terminal window,
change into some suitable directory, and use stack to create our project.
So, we write a stack, new Residention Creole.
And, this will create a new directory for Residention,
and initialize content of that using a Rio template.
Rio is a standard library that I have recently started using.
There are links in the show notes to the home page of the Rio,
and nice tutorial that I read through if you want to learn a little bit more.
We will cover only the very basics while writing the game.
But, Rio is a replacement for the prelude,
which is the standard library that comes with the skill,
and partly it's a standard library, partly it's a framework for writing your games,
sorry, programs, and it will give you a structure of a program
where you can do things like looking and passing configuration.
Easily. But, anyway, now that we have created our project,
we want to edit, because, of course, it's a default settings that the template uses.
So, change to the Residention directory that the stack created,
and have a look at the package.yaml.
This contains a metadata for our project.
And, it is pretty sensible, but we want to change a couple of things in the beginning of the file.
There's a section called it that should point to your public repository if you have one.
License is a machine-readable info about the license terms,
although it's value name codes, and my container is the person who is currently maintaining
the project that is you again.
And then the copyright information goes into the copyright,
and then there's the executable section a little bit down.
And then, our game is called Residance.exe.
So, I removed the dash.exe, so I want our executable to be called
Residance Dungeon.
And, I have a repository at the online,
there's a link in the show notes.
If you want to have a look how the package.yaml looks in my project.
And, now that we have finished the package.yaml,
we are going to have a look at the stack.yaml.
There's another file, and this tells among other things what a resolver to use.
There's a section called Resolver, and we are going to change it to some suitable resolver.
I have used LDS dash 18.27.
So, this specifies which set of libraries to use.
There's a webpage, a stack.yaml, again, link in the show notes,
that hosts a curated set of packages.
So, because there's a lot of different kinds of packages in the Haskell,
and some of those depend on each other.
Managing the dependencies by hand might be a bit freaky if you want to.
For example, package A might depend on the package B,
and package C may depend on the package B,
and if you want to use the A and C packages, both depending on the B,
you have to find a version of the A and C that depend on the version package B,
in a way that all the dependencies are satisfied.
So, A doesn't depend on 2 new or 2 old versions of the package compared to the package B.
And a stack it can do that, a stack for you.
So, they have created a set of packages that they are testing and building,
and when you choose a resolver, you are choosing a certain set of packages.
These are for each package, they might be multiple versions available within each resolver.
So, you're not going to pick just one, but you are.
Basically, a range of packages that are on your disposal.
But, we don't really have to worry about this much,
because our LTS results, LTS stands for the long-term support,
meaning that this package,
could add a package that will be available for quite a while.
So, this is a good search for us.
Okay, and final step is to edit readme.md to site suite your needs.
Basically, write a little bit about what kind of program you are writing,
and if there's any interesting information, or how to build it,
and how to compile it, and how to run it, things like that.
And earlier, when we were editing the package jam, I think, yeah, package jam,
it links to the readme using our, I think it comes via Git.
I don't remember the actually quite sure.
Maybe I can quickly check, but I remember that the package jam
has a section for the readme somewhere.
Yeah, it has the tag called description,
and it's just a link, links to the, you know, in my case, it just says,
please read me at codework at and then the link,
and it gives a direct link to the readme file.
In the opposite result, readme.md that we edit,
will be, if you upload to the codework, it will be the one
that the package.jama is pointing to.
This way, we don't have to write description twice,
this could be, nifty thing to do.
Okay, now we have created a project.
We have edited some of the metadata, and now we are ready to get started with that.
So, first step is to build it.
This is done on the terminal writing stack, build two words,
and this will build the example code that the template
inserted into our project.
There's a one library called, in this case, called a result mansion,
and then there's a one executable, but that is by default,
called the residential exit, but I edited it through the residential.
So, the library and the exit can actually be named with the identical names.
So, a stack will build our project, and it will take a little fifth time,
depending on this project is small, so it shouldn't take a long.
When it has finished, and if everything went correctly,
we can start our exit bootable with stack, exec,
desktop, residential, or residential.exe if we would have edited the name.
And this will print a little message on screen and exit.
So, this just makes sure that our project works.
We can also turn on the verbose locking by starting the project with stack, exec,
that's the residential, that's the verbose, two created and locked.exe.
This won't print anything on the screen, but it will create lock.exe file
that will have the same information as before with some timestamps.
So, the two created and at the end of our command,
tells our computer to redirect the STD error, standard error stream,
into the lock.exe file.
Real is set up in a way that you can use lock commands to lock,
and then it has some commands for writing into the files.
But it doesn't actually have a command on writing directly on screen by default.
So, for our game, we have to import functions for that from the prelude,
but we will look into that later.
So, everything that is outputted on the screen,
in our example now, is actually login done by the program.
If you want, you can have a look at the files.
And see how it is done.
Anyway, and then another useful command is stack test,
which will compile and run tests for the project.
The template comes with a couple of silly tests that don't do much,
that's just an example.
And I don't think we will look that much into the testing in this time,
or later, later time tests are episode I did earlier about testing in Haskell,
that is very, very, very applicable in this situation too.
So, you could have a look at that if you are interested in the testing.
But stack test runs the test.
And then if you want to clean up your project of the intermediate files,
you can just use stack clean.
After this, you have to build the program again with stack build.
Sometimes you might want to, especially when you are trying to remove all the warnings from your code,
because stack does are incremental builds.
So, I mean, GHC does incremental builds too, of course.
But when you build the project for the first time, it will compile all the files.
And after that, if you only compile the files that you have changed,
and the ones that are directly or indirectly,
depending on those changed files.
So, it won't compile everything.
And if you are trying to clean up some errors from,
not errors, but warnings from your project.
If a warning is in a file that you have already compiled,
but you haven't edited, you are not going to see that one again.
That warning, until you clean the project,
then when I build everything, and then you see all the warnings that the compiler is emitting to you.
I like to keep the code as free from the errors as possible.
Basically, my code is to always keep it at the zero warnings, sorry, warnings.
Obviously, zero errors too, but zero warnings.
Because as soon as you start having warnings in your code,
usually it's a compiler telling you that it thinks that you are doing something funny,
and you should have a look at it and see things so that you don't get a runtime exception.
For example, you might also have a code that nobody is using,
nobody's calling, so the compiler will emit that there's a function defined here,
nobody's calling it this, and that is a warning to you, thinking that this is a dead code,
should I just remove it completely?
Because if there's a code that nobody calls, there's no point of keeping it in the project
and maintaining, unless you have a definite plan for using that later.
Another thing is if you are using a doing pattern matching,
you're basically taking some data and telling the program that if the data is in this pattern,
then do this thing, and in this pattern do this thing.
Sometimes you miss a pattern, so that pattern matching isn't complete.
There's a case of some form of data that your program is in handling,
so compiler will emit a warning about that, because if while running the program,
it encounters that type of data, it will crash, and that is, of course, bad.
So we want to keep our code as free for warnings as possible.
Especially if we have more than one people working on the code,
then it's important, so that nobody has to remember that these three warnings are okay,
we don't have to worry about this, it's much easier when you don't have to worry,
I remember such things, just keep code free of warnings.
Anyway, okay, that's about what we are going to use about the stack,
so there's a stack, new for creating a new project, then there's a stack built for building it,
stack exit for executing our binaries, if we have binaries, we might be writing a library,
and then of course we don't have binaries, then there could be a or exitable,
then there's a stack test for running tests, and stack clean for cleaning the intermediate files.
A final thing before finishing, we are going to have a look at the project structure,
there's a three directories in our project at SRC and test.
Up contains the code for how exitable, this is where we will be placing a big portion of the code,
this is basically where the code that deals with the outside world is going to go,
so this is about printing on the screen and asking user input,
it's going to tell the user what is the situation, and it's asking what do you want to do next,
and then it will be this handy user response.
SRC contains code for our library, this is where we will be placing code,
that satisfies the rules of the game, and we are going to keep this part of the program
free from the interactions with the outside world, so if you have a familiar with the terms
pure and impure code, this is the pure part, and it doesn't mean that the another part is
filthy or nasty, it just means that impure just means that it's something that has side effects.
Usually it is dealing with outside world, so SRC contains code that doesn't
deal with the outside world, this is just pure, you will think that it's a pure mathematics,
it's just a data comes in function, does something and returns a response, that's it,
nothing else, data in, data out, no printing on the screen or reading the data on the hard drive,
calling the fax must you know anything, and the third director for use, test,
this is the test list, what I said we are not going to do much with this,
okay, including, we started our card game project, it doesn't do much yet, it prints some
funny message on the screen and that's it, but we already have an executable that we can
build and run, so now we have stuff and only thing left is to modify that
program to look more like a game, and next time we will move into how to roll a new character,
because of course we are going to have some dice rolling, so that we have a randomly generated
character with couple stats, and then maybe even getting then equipped, equipped,
maybe giving them some gear before they venture into the resurrection,
if you have any questions or comments, you can reach me by via email or at the
facebook, where I am to do it at tech.lctp, or even better you could write and record your own episode,
at Astra.
You have been listening to Hacker Public Radio at Hacker Public Radio does work,
today's show was contributed by a HBR listener like yourself, if you ever thought of recording
and click on our contribute link to find out how easy it really is, hosting for HBR has been
kindly provided by www.monsthost.com, the internet archive and our sings.net, on this
otherwise stated, today's show is released under Creative Commons, Attribution 4.0 International
License.