Advanced Functional Programming - Group project (2020)
- ffp
Minesweepskell is a web implementation of the widely known video game Minesweeper fully written in the functional programming language Haskell.
- Minesweeper Web App with three predefined difficulties as well as customisable games
- Slim & blazing fast UI powered by server side events
- Join other players on their game either to view them playing or to play together
- Pause games & continue later
- History of all finished games to revisit your best & worst performances
- REST Backend
- Frontend fully developped in
Yesods
shakespearean templating system - Server-side events in order to provide live UI rerendering and updates for a flawless User Interface, which even has the possibility to play/view one game on multiple Bowsers/Machines simultaneously
- Global state of all ongoing games realized with
TVars
, which provide mutability as well as atomic writing operations - The state only contains all ongoing games, paused and finished (lost/won) games are moved from the in-memory state to the database, if a paused game is continued it will be loaded back into the in-memory state
- As just mentioned Minesweepskell stores non-ongoing games in a database this is realized by using the
Persistent
library to connect aMongoDB
- In order to manipulate and query data types more elegantly
lenses
are used for almost all operations on data types - Lenses for matrices are provided by the
matrix-lens
package and provide elegant manipulation of cells on the game board
Monads
are widely used throughout the project, especially the IO monad for things like state manipulation, as well as Yesods Handler Monad for the REST API, own Monads are not defined- Problem: Initially we wanted to realize the global mutable state with the
State
monad, but we could not get it to work in combination with Yesods handler monad. Due to this we switched to TVars for the global in-memory state, which proved to be a better choice, since it even provides atomic writing operations and was astonishingly smooth to implement for our use cases.
Run in the project folder stack build
.
$ stack --version
Version 2.3.3 x86_64
$ yesod version
yesod-bin version: 1.6.0.6
- Install haskell-stack and yesod
# - if it fails run `xcode-select --install before`
brew install haskell-stack
stack install yesod-bin --install-ghc
- Add yesod installation path to your shell
# ~/.zshrc
export PATH=$HOME/.local/bin:$PATH
If you have trouble, refer to the Yesod Quickstart guide for additional detail.
- Install MongoDB
brew tap mongodb/brew
brew install [email protected]
- Run MongoDB
brew services start [email protected]
brew services stop [email protected]
- Verify that it is running
ps aux | grep -v grep | grep mongod
, logs can be found here/usr/local/var/log/mongodb/mongo.log.
and settings here/usr/local/etc/mongod.conf
For more information take a look at https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/
- Use MongoDB Compass as GUI
stack build && stack exec -- yesod devel
to run the project locally.
- Build libraries:
stack build
- Start a development server with
stack exec -- yesod devel
, it watches for changes and recompiles the project automatically. - Go to http://localhost:3000 to see landing page
- Run
stack clean --full && stack build
to clean the project and to rebuild it.
- add the following to your
~/.ghc/ghci.conf
:set prompt λ:
:set prompt-cont λ|
https://stackoverflow.com/a/47694134
stack test --flag minesweepskell:library-only --flag minesweepskell:dev
(Because yesod devel
passes the library-only
and dev
flags, matching those flags means you don't need to recompile between tests and development, and it disables optimization to speed up your test compile times).
yesod
mongodb
persistent
lens
matrix-lens
...
For more details take a look at the package.yaml.
Along with the IntelliJ plugin for Haskell Ormolu is used as automatic code formatter.
- Andreas Ellwanger
- Timo Erdelt
- Andreas Griesbeck
Due to the small group size of 3 it is impossible for us to properly distinguish what of our project has been done by whom. We all worked on all parts of our application, especially since we mostly did “pair-programming” (with two or often all three of us working together). So all of us were equally involved in all parts of our application. We would be happy to answer questions about our development process, as well as our individual/collective contributions at the examination.