- Create a new project called working-with-cloud-haskell with the simple stack template:
stack new working-with-cloud-haskell simple
- Add a dependency on the distributed-process library in the build-depends sub-section of executable section. Also add support libraries and the -threaded option to ghc-options:
executable working-with-cloud-haskell hs-source-dirs: src main-is: Main.hs ghc-options: -threaded default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , binary , distributed-process , network-transport , network-transport-tcp
At the time of writing this recipe, the Cloud Haskell libraries are not part of LTS stack. Hence we need to add more dependencies to stack.yaml in the extra-deps section. Note that the version numbers may change in future, and you might have to adjust them:
extra-deps: - distributed-process-0.6.6 - syb-0.6 - network-transport-tcp-0.5.1
- Open src/Main.hs. We will be adding our source here. Add the DeriveGeneric extension to auto-derive the Binary instance:
{-# LANGUAGE DeriveGeneric #-} module Main where import Control.Concurrent import Control.Monad import Control.Distributed.Process import Control.Distributed.Process.Node import Network.Transport.TCP import Network.Transport (Transport) import Data.Binary (Binary) import GHC.Generics
- Create a transport serving on port 10501:
localTransport :: IO Transport localTransport = do Right t <- createTransport "127.0.0.1" "10501"
defaultTCPParameters return t
- Create a Process to welcome the user with a greeting:
type UserId = String data UserIntimation = UserIntimation ProcessId UserId deriving
(Show, Generic) instance Binary UserIntimation welcome :: UserIntimation -> Process () welcome (UserIntimation pid uid) = send pid $ "Welcome to Cloud
Haskell, " ++ uid
- Create a Process to define some distributed work. Accept a message and give back a reply:
greet :: Process () greet = forever $ receiveWait [match welcome]
- Run the nodes in the main function:
main :: IO () main = do t <- localTransport node <- newLocalNode t initRemoteTable runProcess node $ do self <- getSelfPid greetPid <- spawnLocal greet -- Continue with greetings say "Greeting Rudy!" send greetPid (UserIntimation self "Rudy") greeting <- expectTimeout 1000000 case greeting of Nothing -> die "Greet server not up?" Just g -> say $ "Greetings says : " ++ g -- Wait for all distributed messages to finish exchanging
befor exiting liftIO $ threadDelay 1000000
- Build and execute the project:
stack build stack exec -- working-with-cloud-haskell
- You should see following output:
