### Execute Key-Value Store (Bash) Source: https://github.com/gshen42/haschor/blob/main/examples/kvs-3-higher-order/README.md Commands to start and interact with the key-value store in primary-backup mode. Includes starting the primary and backup nodes, and a client for PUT and GET operations. Assumes `cabal` is installed and the project is built. ```bash # start primary cabal run kvs3 primary # on a different terminal, start backup cabal run kvs3 backup # another terminal for client cabal run kvs3 client GET hello > Nothing PUT hello world > Just "world" GET hello > Just "world" ``` -------------------------------- ### Running the Simple Bookseller Example Source: https://github.com/gshen42/haschor/blob/main/examples/bookseller-1-simple/README.md Provides instructions on how to execute the bookseller example using Cabal. It details the commands to run the buyer and seller processes in separate shells and shows example interactions, including prompts for book titles and the expected output for successful purchases and out-of-budget scenarios. ```bash # in shell 1 cabal run bookseller-1-simple buyer # in shell 2 cabal run bookseller-1-simple seller # shell 1 will prompt the user to type in the book they want to buy > Enter the title of the book to buy Types and Programming Languages # shell 1 will return the delivery date it receives from the seller or out of budget # then both programs terminate > The book will be delivered on 2022-12-19 # if we run the choreography again with a different book to buy # in shell 1 cabal run bookseller-1-simple buyer # in shell 2 cabal run bookseller-1-simple seller # in shell 1 > Enter the title of the book to buy Homotopy Type Theory # in shell 1 > The book's price is out of the budget ``` -------------------------------- ### Run HasChor Executable Examples Source: https://github.com/gshen42/haschor/blob/main/README.md Demonstrates how to execute HasChor examples using the cabal run command. This requires the HasChor library to be installed and the examples to be present in the 'examples' directory. The command takes the executable name and a location as arguments. ```bash cabal run executable-name location ``` -------------------------------- ### HTTP Backend Configuration for Distributed Execution in Haskell Source: https://context7.com/gshen42/haschor/llms.txt This example shows how to configure HTTP endpoints for distributed execution in Choreography. It defines network locations for different participants using `mkHttpConfig` and initiates a simple choreography, sending a message from 'buyer' to 'seller'. ```haskell #{-# LANGUAGE DataKinds #-} import Choreography import System.Environment (getArgs) main :: IO () main = do [loc] <- getArgs runChoreography httpConfig myChoreography loc return () where httpConfig = mkHttpConfig [ ("buyer", ("localhost", 4242)) , ("seller", ("localhost", 4343)) , ("deliverer", ("localhost", 4444)) ] myChoreography :: Choreo IO (String @ "buyer") myChoreography = do msg <- buyer `locally` \_ -> return "Hello" (buyer, msg) ~> seller -- Run with: cabal run my-program buyer -- cabal run my-program seller (in another terminal) ``` -------------------------------- ### Haskell Functions for Book Pricing and Delivery Source: https://github.com/gshen42/haschor/blob/main/examples/bookseller-1-simple/README.md Defines partial functions in Haskell to determine the price and delivery date of specific books. These functions are used by the seller in the bookseller protocol. They take a book title (String) as input and return its price (Int) or delivery date (Day). The functions are partial, meaning they are only defined for a limited set of book titles. ```haskell priceOf :: String -> Int priceOf "Types and Programming Languages" = 80 priceOf "Homotopy Type Theory" = 120 deliveryDateOf :: String -> Day deliveryDateOf "Types and Programming Languages" = fromGregorian 2022 12 19 deliveryDateOf "Homotopy Type Theory" = fromGregorian 2023 01 01 ``` -------------------------------- ### Bookshop Protocol Choreography in Haskell using HasChor Source: https://github.com/gshen42/haschor/blob/main/README.md Implements a bookshop protocol where a buyer, seller, and deliverer interact. It uses HasChor's `Choreo` monad for distributed programming, `locally` for actions at specific locations, `~>` for communication, and `cond` for conditional logic. The `main` function configures and runs the choreography using an HTTP backend. ```haskell {-# LANGUAGE BlockArguments #} {-# LANGUAGE DataKinds #} {-# LANGUAGE LambdaCase #} {-# LANGUAGE TypeOperators #} module Main where import Choreography (Choreo, cond, locally, mkHttpConfig, runChoreography, type (@), (~>)) import Control.Monad (void) import Data.Proxy (Proxy (..)) import System.Environment (getArgs) buyer :: Proxy "buyer" buyer = Proxy seller :: Proxy "seller" seller = Proxy deliverer :: Proxy "deliverer" deliverer = Proxy priceOf :: String -> Int priceOf "Types and Programming Languages" = 80 priceOf "Homotopy Type Theory" = 120 priceOf _ = 100 type Date = String deliveryDateOf :: String -> Date deliveryDateOf "Types and Programming Languages" = "2002-01-04" deliveryDateOf "Homotopy Type Theory" = "2013-04-20" deliveryDateOf _ = "1970-01-01" budget :: Int budget = 100 bookshop :: Choreo IO (Maybe Date @ "buyer") bookshop = do title <- buyer `locally` \un -> getLine title' <- (buyer, title) ~> seller price <- seller `locally` \un -> return $ priceOf (un title') price' <- (seller, price) ~> buyer decision <- buyer `locally` \un -> return $ (un price') <= budget cond (buyer, decision) \case True -> do title'' <- (seller, title') ~> deliverer date <- deliverer `locally` \un -> return $ deliveryDateOf (un title'') date' <- (deliverer, date) ~> seller date'' <- (seller, date') ~> buyer buyer `locally` \un -> do putStrLn $ "The book will be delivered on " ++ (un date'') return $ Just (un date'') False -> buyer `locally` \un -> do putStrLn "The book is out of the budget" return Nothing main :: IO () main = do [loc] <- getArgs void $ runChoreography cfg bookshop loc where cfg = mkHttpConfig [ ("buyer", ("localhost", 4242)) , ("seller", ("localhost", 4343)) , ("deliverer", ("localhost", 4444)) ] ``` -------------------------------- ### Complete Bookseller Protocol in Haskell Source: https://context7.com/gshen42/haschor/llms.txt This is a full implementation of a three-party book purchasing protocol using Choreography. It involves a buyer, seller, and deliverer, handling book selection, price negotiation, budget checking, and delivery date confirmation. The configuration uses HTTP endpoints for communication. ```haskell #{-# LANGUAGE BlockArguments #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeOperators #-} module Main where import Choreography import Data.Proxy (Proxy(..)) import System.Environment (getArgs) buyer :: Proxy "buyer" buyer = Proxy seller :: Proxy "seller" seller = Proxy deliverer :: Proxy "deliverer" deliverer = Proxy budget :: Int budget = 100 priceOf :: String -> Int priceOf "Types and Programming Languages" = 80 priceOf "Homotopy Type Theory" = 120 priceOf _ = 100 type Date = String deliveryDateOf :: String -> Date deliveryDateOf "Types and Programming Languages" = "2002-01-04" deliveryDateOf "Homotopy Type Theory" = "2013-04-20" deliveryDateOf _ = "1970-01-01" bookshop :: Choreo IO (Maybe Date @ "buyer") bookshop = do -- Buyer inputs book title title <- buyer `locally` \un -> getLine title' <- (buyer, title) ~> seller -- Seller looks up price and sends to buyer price <- seller `locally` \un -> return $ priceOf (un title') price' <- (seller, price) ~> buyer -- Buyer decides based on budget decision <- buyer `locally` \un -> return $ (un price') <= budget cond (buyer, decision) \case True -> do -- Send title to deliverer and get delivery date title'' <- (seller, title') ~> deliverer date <- deliverer `locally` \un -> return $ deliveryDateOf (un title'') date' <- (deliverer, date) ~> seller date'' <- (seller, date') ~> buyer buyer `locally` \un -> do putStrLn $ "The book will be delivered on " ++ (un date'') return $ Just (un date'') False -> buyer `locally` \un -> do putStrLn "The book is out of the budget" return Nothing main :: IO () main = do [loc] <- getArgs runChoreography cfg bookshop loc return () where cfg = mkHttpConfig [ ("buyer", ("localhost", 4242)) , ("seller", ("localhost", 4343)) , ("deliverer", ("localhost", 4444)) ] -- Run three instances: -- Terminal 1: cabal run bookshop buyer -- Terminal 2: cabal run bookshop seller -- Terminal 3: cabal run bookshop deliverer ``` -------------------------------- ### Haskell Key-Value Store Client-Server Choreography Source: https://context7.com/gshen42/haschor/llms.txt Implements a client-server key-value store using HasChor. It defines types for state, requests, and responses. The choreography involves sending requests from the client to the server, handling them locally on the server, and returning responses. It uses `IORef` for mutable state on the server and demonstrates a loop for continuous interaction. Dependencies include the 'choreography' library, 'containers', and 'network'. ```Haskell {-# LANGUAGE BlockArguments #} {-# LANGUAGE DataKinds #} {-# LANGUAGE LambdaCase #} module Main where import Choreography import Data.IORef import Data.Map (Map) import qualified Data.Map as Map import Data.Proxy (Proxy(..)) import System.Environment (getArgs) client :: Proxy "client" client = Proxy server :: Proxy "server" server = Proxy type State = Map String String data Request = Put String String | Get String deriving (Show, Read) type Response = Maybe String readRequest :: IO Request readRequest = do putStrLn "Command? (GET key or PUT key value)" line <- getLine case words line of ["GET", k] -> return (Get k) ["PUT", k, v] -> return (Put k v) _ -> putStrLn "Invalid command" >> readRequest handleRequest :: Request -> IORef State -> IO Response handleRequest request stateRef = case request of Put key value -> do modifyIORef stateRef (Map.insert key value) return (Just value) Get key -> do state <- readIORef stateRef return (Map.lookup key state) kvs :: Request @ "client" -> IORef State @ "server" -> Choreo IO (Response @ "client") kvs request stateRef = do request' <- (client, request) ~> server response <- server `locally` \unwrap -> handleRequest (unwrap request') (unwrap stateRef) (server, response) ~> client mainChoreo :: Choreo IO () mainChoreo = do stateRef <- server `locally` \_ -> newIORef (Map.empty :: State) loop stateRef where loop :: IORef State @ "server" -> Choreo IO () loop stateRef = do request <- client `locally` \_ -> readRequest response <- kvs request stateRef client `locally` \unwrap -> putStrLn ("> " ++ show (unwrap response))) loop stateRef main :: IO () main = do [loc] <- getArgs case loc of "client" -> runChoreography config mainChoreo "client" "server" -> runChoreography config mainChoreo "server" return () where config = mkHttpConfig [ ("client", ("localhost", 3000)) , ("server", ("localhost", 4000)) ] -- Terminal 1: cabal run kvs1 server -- Terminal 2: cabal run kvs1 client -- Example interaction: -- Command? (GET key or PUT key value) -- PUT name Alice -- > Just "Alice" -- Command? (GET key or PUT key value) -- GET name -- > Just "Alice" ``` -------------------------------- ### Defining Locations in Haskell with DataKinds and Proxy Source: https://context7.com/gshen42/haschor/llms.txt This snippet demonstrates how to define distinct locations (nodes) in a distributed system using Haskell's DataKinds and Proxy types. Locations are represented by type-level strings and term-level Proxy values, allowing for static type checking of communication endpoints. Template Haskell can also be used for automatic generation. ```haskell #{-# LANGUAGE DataKinds #-} import Data.Proxy (Proxy(..)) -- Define locations manually as Proxy values buyer :: Proxy "buyer" buyer = Proxy seller :: Proxy "seller" seller = Proxy deliverer :: Proxy "deliverer" deliverer = Proxy -- Alternatively, use Template Haskell to generate locations -- mkLoc "buyer" generates both type and term level definitions ``` -------------------------------- ### Communication Between Locations using `(~>)` in Haskell Source: https://context7.com/gshen42/haschor/llms.txt The `(~>)` operator facilitates sending values between two specified locations. It takes a tuple containing the sender's location and the value to be sent, and the receiver's location. The received value is then available at the receiver's location, typed appropriately. ```haskell #{-# LANGUAGE BlockArguments #-} #{-# LANGUAGE DataKinds #-} #{-# LANGUAGE TypeOperators #-} import Choreography -- Send a value from buyer to seller communication :: Choreo IO (String @ "seller") communication = do -- Buyer creates a title title <- buyer `locally` \_ -> do putStrLn "Enter book title:" getLine -- Send title from buyer to seller titleAtSeller <- (buyer, title) ~> seller -- Seller can now use the title seller `locally` \un -> do let receivedTitle = un titleAtSeller putStrLn $ "Seller received: " ++ receivedTitle return titleAtSeller ``` -------------------------------- ### Conditional Execution with `cond'` in Haskell Source: https://context7.com/gshen42/haschor/llms.txt This snippet demonstrates conditional execution in Choreography, where a branch is taken based on the result of a local computation performed by a participant. It uses the `cond'` function for branching and local computations to determine the execution path. ```haskell #{-# LANGUAGE BlockArguments #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE LambdaCase #-} import Choreography conditionalWithComputation :: Choreo IO (String @ "buyer") conditionalWithComputation = do price <- seller `locally` \_ -> return 120 priceAtBuyer <- (seller, price) ~> buyer -- Compute decision and branch in one step cond' (buyer, \un -> return $ (un priceAtBuyer) <= 100) \case True -> do buyer `locally` \_ -> do putStrLn "Within budget!" return "Purchasing" False -> do buyer `locally` \_ -> do putStrLn "Over budget!" return "Cancelled" ``` -------------------------------- ### Combined Computation and Communication with `(~~>)` in Haskell Source: https://context7.com/gshen42/haschor/llms.txt The `(~~>)` operator streamlines the process of performing a local computation at one location and immediately sending its result to another location. This combines the `locally` and `(~>)` operations into a single, more concise step, simplifying distributed workflows. ```haskell #{-# LANGUAGE BlockArguments #-} #{-# LANGUAGE DataKinds #-} import Choreography -- Compute and send in one operation simplifiedCommunication :: Choreo IO (Int @ "buyer") simplifiedCommunication = do title <- buyer `locally` \_ -> getLine -- Seller computes price and sends to buyer in one step price <- (seller, \un -> return $ priceOf (un title)) ~~> buyer buyer `locally` \un -> do putStrLn $ "Price: " ++ show (un price) return price where priceOf :: String -> Int priceOf "Types and Programming Languages" = 80 priceOf _ = 100 ``` -------------------------------- ### Conditional Choreography Execution with `cond` in Haskell Source: https://context7.com/gshen42/haschor/llms.txt The `cond` function allows for branching in choreographies based on a condition evaluated at a specific location. It takes the location where the condition is evaluated and the condition itself, followed by a lambda case that defines the different choreography branches to execute based on the boolean outcome of the condition. ```haskell #{-# LANGUAGE BlockArguments #-} #{-# LANGUAGE DataKinds #-} #{-# LANGUAGE LambdaCase #-} import Choreography conditionalExample :: Choreo IO (Maybe String @ "buyer") conditionalExample = do -- Buyer decides whether to proceed decision <- buyer `locally` \_ -> do putStrLn "Proceed? (yes/no)" response <- getLine return (response == "yes") -- Branch based on buyer's decision cond (buyer, decision) \case True -> do result <- seller `locally` \_ -> return "Order confirmed" resultAtBuyer <- (seller, result) ~> buyer buyer `locally` \un -> do putStrLn $ un resultAtBuyer return $ Just (un resultAtBuyer) False -> do buyer `locally` \_ -> do putStrLn "Order cancelled" return Nothing ``` -------------------------------- ### Local Computation with `locally` in Haskell Source: https://context7.com/gshen42/haschor/llms.txt The `locally` function in HasChor executes a computation within the context of a specific location. It returns a located value, meaning the result is tied to the location where it was computed. The `unwrap` function provided to the local computation can only be used to access values within that same location, enforcing locality. ```haskell #{-# LANGUAGE BlockArguments #-} #{-# LANGUAGE DataKinds #-} import Choreography -- Perform a local computation at the buyer location example :: Choreo IO (String @ "buyer") example = buyer `locally` \unwrap -> do putStrLn "Enter book title:" title <- getLine return title -- The unwrap function can only unwrap values at the current location exampleWithUnwrap :: Choreo IO (Int @ "seller") exampleWithUnwrap = do price <- seller `locally` \_ -> return 100 -- Inside seller's locally block, we can access price seller `locally` \un -> do let actualPrice = un price -- unwrap works here putStrLn $ "Price is: " ++ show actualPrice return actualPrice ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.