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-platform
package 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 [email protected]: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
Demo
module inghci
:- If you are running it online, press "Run".
This will launch
ghci
and load theDemo
module. - If you are running it locally, launch a terminal, navigate to the
HaskellIntro
directory that you downloaded/cloned, and runghci
. Type:l Demo
to loadDemo
.- To quit
ghci
, type:q
.
- To quit
ghci
is 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
MsgSys
into 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
Demo
module gives you access to:- Two instances of the type
MsgSys
—msgSys0
andmsgSys1
; - Three
LoggedInUser
s —alerter
,ose
andpedro
; - 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 ose
prints:ose :: LoggedInUser
and typing
:t alert
prints:alert :: Message -> User -> MsgSys -> MsgSys
-
There are two ways to view values like
msgSys1
andose
:-
Type its name into
ghci
and 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
display
function 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 msgSys1
and compare it to what you get when you typemsgSys1
to see what I mean.-
You can use
display
to 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
display
does 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 thatMsgSys
exports (type names begin with capital letters), which can be used by the Demo module.- These types are returned by the exported functions.
display
can print instances of all of these exported types, and lists of these types.
-
Open Demo.hs in a text editor.
-
Add code that
register
s two newUser
s tomsgSys1
.- The
initialise
function at the bottom of the file demonstrates how to do this. - You can either:
- modify
initialise
, and the call toinitialise
at the top of the file; - or write a new function with type signature
MsgSys -> MsgSys
that takesmsgSys1
and returns the result of registering the two newUser
s.
- modify
- Remember: you can type
:t register
inghci
to viewregister
's type signature (or you can just search for the implementation ofregister
in MsgSys.hs).
- The
-
Reload Demo.hs in
ghci
(i.e. run:l Demo
again), to make sure it compiles.- Feel free to ask me for help if you have any issues.
-
Type
display (allUsers <new MsgSys>)
inghci
to check that your newUser
s exist, where<new MsgSys>
is the result of your new calls toregister
. -
In Demo.hs:
- Use the
findUser
function to search for one of these newUser
s by theirName
(its type signature shows you how to use it) and name the resultingUser
(e.g.myUser = findUser ...
). - Use the
login
function to log in as the other newUser
, and name the resultingLoggedInUser
. - Use the
send
function to send aMessage
from your newLoggedInUser
to your newUser
, and name the resultingMsgSys
.- Note: if you want to
send
aMessage
to aLoggedInUser
, you have to use theasUser
function to extract theUser
that it contains.
- Note: if you want to
- Use the
-
Reload Demo.hs in
ghci
anddisplay
the newMsgSys
that you have created. -
Try out some of the functions that we wrote in the presentation, e.g.:
alertOutOfSpace
,usedSpace
andalertMultiOutOfSpace
. -
Have a go at writing the
sendMulti
function 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.