How to do it...

  1. Create a new project called working-with-cloud-haskell with the simple stack template:
        stack new working-with-cloud-haskell simple
  1. 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
  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
  1. Create a transport serving on port 10501:
        localTransport :: IO Transport
        localTransport = do
          Right t <- createTransport "127.0.0.1" "10501" 
defaultTCPParameters return t
  1. 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
  1. Create a Process to define some distributed work. Accept a message and give back a reply:
        greet :: Process ()
        greet = forever $ receiveWait [match welcome]
  1. 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
  1. Build and execute the project:
        stack build
        stack exec -- working-with-cloud-haskell
  1. You should see following output: