This fork will not be updated for Elm 0.19. We have a forthcoming project which will be easier for beginners.
($ character denotes the beginning of a prompt, it should not be included.)
$ curl -sSL https://get.haskellstack.org/ | sh
Consult the installation guide if you’re on Windows.
$ git clone https://github.com/emilyhorsman/elm-haskell-stm.git
$ cd elm-haskell-stm
$ stack setup
$ stack build
$ stack exec elm-haskell-stm-exe
$ elm-package install
$ elm-reactor
- All Haskell is run through stylish-haskell and hlint
- All Elm is run through elm-format
app/Main.hsis merely an entry point and has no application logic.src/Lib.hscontains the serverApplication, creates the central channel, and handles each WebSocket connection.src/HighScores.hscontains the application logic and handles the message channels.
- The server creates a new
TChanforCentralMessages. This is called the central channel. There is one for the entire server. - The server forks a thread that will run for the entire lifecycle. This thread holds the server state and reads from the central message channel. This is called the central thread.
- A browser opens a WebSocket connection to the application.
- The web server forks a thread to handle this connection.
Lib.wsAppis called and accepts the connection.wsAppcreates a newTChanforClientMessages. This is a client channel. There is one per WebSocket connection.wsAppforks two threads that will run for the lifecycle of this client.- One thread reads from the newly created channel.
- One thread reads from the WebSocket connection.
wsAppwrites aNewUserCentralMessageto the central channel. It writes a reference to the client channel and WebSocket connection with the message.HighScores.processCentralChanrunning on the central thread reads theNewUsermessage.- The central thread adds the client channel to the server state.
- The central thread writes an
AssignUsernamemessage to the client channel.- The client thread reads the
AssignUsernamemessage and writes to the WebSocket connection.- The Elm application receives a
WSReceiveMessagemessage in itsupdatefunction.
- The Elm application receives a
- The client thread reads the
- The central thread writes an
AssignScoreclient message for each existing score to the current client channel.- The client thread reads the
AssignScoremessage and writes to the WebSocket connection.- The Elm application receives a
WSReceiveMessagemessage in itsupdatefunction.
- The Elm application receives a
- The client thread reads the
- The central thread writes an
AssignScoreclient message about the new user to all other client channels.- Each of the other client threads reads this
AssignScoremessage and writes to their WebSocket connections.- The Elm applications each receive a
WSReceiveMessagemessage in theirupdatefunction.
- The Elm applications each receive a
- Each of the other client threads reads this
- The Elm application receives a
Clickmessage in itsupdatefunction. - The
updatefunction returns aCmdto send the associated username across the WebSocket connection. - The thread reading that connection writes an
Eventcentral message to the central channel. - The central thread reads the
Eventmessage. - The central thread updates the score and writes an
AssignScoreclient message to all client channels.- Each client thread reads this
AssignScoremessage and writes to their WebSocket connections.- The Elm applications each receive a
WSReceiveMessagemessage in theirupdatefunction.
- The Elm applications each receive a
- Each client thread reads this
-
this is the same as |> in Elm, but for IO actions, os
f >>= gis the same as
do x <- f g x'if
gdoesn't have a return value, ordo x <- f return (g x')if it does have a return value