Author: Ose Pedro
This repository contains a basic implementation of the messaging system that I used as a running example in my "Introduction to Functional Programming" presentation.
The easiest way to start playing around with the messaging system is to use this repl.it installation. If you want to save your changes, you should probably sign up for a free account (I don't know how long they'll keep your changes for if you don't).
If you'd rather play with a local copy of the code, you'll need to do the following:
-
Install Haskell: follow these instructions. I don't think you need to follow the step about installing Stack.
-
I've only done this in Ubuntu, where it's as simple as launching a terminal and running
sudo apt-get update sudo apt-get install haskell-platform -
The Mac OS X installation procedure looks straightforward too. I don't have a Mac though, so I can't confirm this.
-
The Windows installation procedure looks horrible - I don't know why it's like this. If you want to give it a try, this video might help.
- It might be easier to install Ubuntu 20.04 (e.g. in Windows Subsystem for Linux or in a VM), and then install the
haskell-platformpackage as described above.
- It might be easier to install Ubuntu 20.04 (e.g. in Windows Subsystem for Linux or in a VM), and then install the
-
-
Download this repository:
- Option A (easiest): download the zip file from here and extract its contents.
- Option B: clone the Git repository:
-
If you don't already have Git, use these instructions to get it.
-
Launch a terminal and run
git clone git@github.com:OsePedro/HaskellIntro.git
-
-
Text editor: You'll need a text editor to edit the code. If you want syntax highlighting, try one of the following:
- Visual Studio Code with the Haskell extension;
- Atom with the language-haskell package.
- If you're a Sublime user, you can try the SublimeHaskell package.
-
Load the
Demomodule inghci:- If you are running it online, press "Run".
This will launch
ghciand load theDemomodule. - If you are running it locally, launch a terminal, navigate to the
HaskellIntrodirectory that you downloaded/cloned, and runghci. Type:l Demoto loadDemo.- To quit
ghci, type:q.
- To quit
ghciis a REPL — an interactive environment in which you can execute arbitrary Haskell expressions. It allows us to play around with the messaging system without having to write a user interface.- Note that it also gives you direct access to parts of the system that it would be unwise to allow users to directly manipulate.
E.g. it allows you to put
MsgSysinto invalid states that would not otherwise be reachable through the functions exported by the MsgSys module.
- Note that it also gives you direct access to parts of the system that it would be unwise to allow users to directly manipulate.
E.g. it allows you to put
- The loaded
Demomodule gives you access to:- Two instances of the type
MsgSys—msgSys0andmsgSys1; - Three
LoggedInUsers —alerter,oseandpedro; - All of the functions and types described in the presentation.
- Two instances of the type
- If you are running it online, press "Run".
This will launch
-
Type
:t <value/function name>to view the type of any value or function. E.g. typing:t oseprints:ose :: LoggedInUserand typing
:t alertprints:alert :: Message -> User -> MsgSys -> MsgSys -
There are two ways to view values like
msgSys1andose:-
Type its name into
ghciand press enter. This will print a Haskell expression that represents the full state of the value. E.g. if you typeose, it will print:Just (RawCredentials {credsUser = RawUser (StringWrapper "Ose"), credsPassword = StringWrapper "Ose's unguessable password"}) -
Use the
displayfunction to print a more readable representation of the value. This is especially useful forMsgSys, as their Haskell expressions are long and poorly formatted. Try executingdisplay msgSys1and compare it to what you get when you typemsgSys1to see what I mean.-
You can use
displayto view instances of pretty much all types defined in the MsgSys module, and lists of these types. E.g. if you typedisplay ose, it will print:User: Ose Password: Ose's unguessable password -
The few types that
displaydoes not support are simple enough to be viewed as described in the previous point.
-
-
-
Open MsgSys.hs in a text editor. You will see a line near the top that says
module MsgSys. The list of names in parentheses after that are the values, functions and types thatMsgSysexports (type names begin with capital letters), which can be used by the Demo module.- These types are returned by the exported functions.
displaycan print instances of all of these exported types, and lists of these types.
-
Open Demo.hs in a text editor.
-
Add code that
registers two newUsers tomsgSys1.- The
initialisefunction at the bottom of the file demonstrates how to do this. - You can either:
- modify
initialise, and the call toinitialiseat the top of the file; - or write a new function with type signature
MsgSys -> MsgSysthat takesmsgSys1and returns the result of registering the two newUsers.
- modify
- Remember: you can type
:t registeringhcito viewregister's type signature (or you can just search for the implementation ofregisterin MsgSys.hs).
- The
-
Reload Demo.hs in
ghci(i.e. run:l Demoagain), to make sure it compiles.- Feel free to ask me for help if you have any issues.
-
Type
display (allUsers <new MsgSys>)inghcito check that your newUsers exist, where<new MsgSys>is the result of your new calls toregister. -
In Demo.hs:
- Use the
findUserfunction to search for one of these newUsers by theirName(its type signature shows you how to use it) and name the resultingUser(e.g.myUser = findUser ...). - Use the
loginfunction to log in as the other newUser, and name the resultingLoggedInUser. - Use the
sendfunction to send aMessagefrom your newLoggedInUserto your newUser, and name the resultingMsgSys.- Note: if you want to
sendaMessageto aLoggedInUser, you have to use theasUserfunction to extract theUserthat it contains.
- Note: if you want to
- Use the
-
Reload Demo.hs in
ghcianddisplaythe newMsgSysthat you have created. -
Try out some of the functions that we wrote in the presentation, e.g.:
alertOutOfSpace,usedSpaceandalertMultiOutOfSpace. -
Have a go at writing the
sendMultifunction suggested on the final slide. I'll share the solution later.
- If there's enough demand, I'll happily do another talk in future about some of the things at the bottom of the Summary slide.
- This will help you to understand more of what's going on in MsgSys.hs.
- A Gentle Introduction to Haskell — a short and sweet tutorial.
- Learn You a Haskell for Great Good — I've barely read any of this, but what I've seen so far seems good, and it's free to read online.
I created this image for the presentation, then changed my mind about using it. But I like it so much that I thought it would be a shame not to share it with the world. I'll send £10 to the first person who correctly guesses how I was going to relate it to the presentation.