### Install purescript-run with Spago Source: https://github.com/natefaubion/purescript-run/blob/master/README.md This command installs the purescript-run package using the Spago package manager. Spago is the standard build tool and package manager for PureScript projects, handling dependencies and builds. ```Shell spago install run ``` -------------------------------- ### PureScript DSL Combination: Coproduct Example Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Demonstrates combining two DSLs (Talk and Dinner) using Coproduct, which acts as an 'Either' for Functors. This approach requires explicit lifting of DSL operations. ```purescript data LovelyEveningF a = Dining (DinnerF a) | Talking (TalkF a) type LovelyEvening = Free LovelyEveningF -- Explicitly lift DSLs into the composite type liftDinner :: Dinner ~> LovelyEvening liftDinner = hoistFree Dining liftTalk :: Talk ~> LovelyEvening liftTalk = hoistFree Talking dinnerTime :: LovelyEvening Unit dinnerTime = do liftTalk $ speak "I'm famished!" isThereMore <- liftDinner $ eat Pizza if isThereMore then dinnerTime else do bill <- liftDinner checkPlease liftTalk $ speak "Outrageous!" ``` -------------------------------- ### PureScript Free Monad DSL: Dinner Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Defines a DSL for dinner-related actions, such as eating food and checking the bill. This serves as another example for creating composable DSLs with the Free monad. ```purescript type IsThereMore = Boolean type Bill = Int data DinnerF a = Eat Food (IsThereMore -> a) | CheckPlease (Bill -> a) type Dinner = Free DinnerF -- Insert boilerplate here ``` -------------------------------- ### PureScript Combined Logging and Sleeping Program Source: https://github.com/natefaubion/purescript-run/blob/master/README.md An example program that composes logging and sleeping effects. It first logs a message, then waits for 3000 milliseconds, and finally logs another message. ```PureScript program :: forall r. Run (SLEEP + LOG + r) Unit program = do log "I guess I'll wait..." sleep 3000 log "I can't wait any longer!" ``` -------------------------------- ### PureScript Extensible DSLs: Combined Program Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Demonstrates a program that seamlessly uses multiple DSLs combined via VariantF. This showcases the power of extensible sums for creating unified DSL interfaces without explicit lifting. ```purescript type LovelyEvening r = (DINNER + TALK + r) dinnerTime :: forall r. Free (VariantF (LovelyEvening + r)) Unit dinnerTime = do speak "I'm famished!" isThereMore <- eat Pizza if isThereMore then dinnerTime else do bill <- checkPlease speak "Outrageous!" ``` -------------------------------- ### PureScript Extensible DSLs: VariantF Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Introduces VariantF for extensible sum types, enabling the combination of DSLs without manual lifting or defining new composite data types. Shows how to define types and operations using VariantF and proxies. ```purescript type TALK r = (talk :: TalkF | r) _talk = Proxy :: Proxy "talk" speak :: forall r. String -> Free (VariantF (TALK + r)) Unit speak str = liftF (inj _talk (Speak str unit)) listen :: forall r. Free (VariantF (TALK + r)) String listen = liftF (inj _talk (Listen identity)) --- type DINNER r = (dinner :: DinnerF | r) _dinner = Proxy :: Proxy "dinner" eat :: forall r. Food -> Free (VariantF (DINNER + r)) IsThereMore eat food = liftF (inj _dinner (Eat food identity)) checkPlease :: forall r. Free (VariantF (DINNER + r)) Bill checkPlease = liftF (inj _dinner (CheckPlease identity)) ``` -------------------------------- ### PureScript Interpreting Effects with Continuations Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Demonstrates how to interpret a `Run` program that uses custom effects (like `log` and `sleep`) into a base `Effect` using continuation-passing style. It defines how to handle each effect constructor (`Log`, `Sleep`) within the `match` function. ```PureScript program2 :: Effect Unit program2 = program # runCont go done where go = match { log: \(Log str cb) -> Console.log str *> cb , sleep: \(Sleep ms cb) -> void $ setTimeout ms cb } done _ = do Console.log "Done!" ``` -------------------------------- ### PureScript Free Monad DSL Interpreter: Talk Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Provides an interpreter for the Talk DSL, demonstrating how to execute a Free monad program. It uses foldFree to pattern match on the DSL's Functor and map it to an Effect. ```purescript main :: Effect Unit main = foldFree go program where go :: TalkF ~> Effect go = case _ of -- Just log any speak statement Speak str next -> do Console.log str pure next -- Reply to anything with "I am Groot", but maybe -- we could also get input from a terminal. Listen reply -> do pure (reply "I am Groot") ``` -------------------------------- ### PureScript Talk Effect and Program Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Defines a simple `TalkF` effect for speaking and listening, lifts it into the `Run` monad, and creates a basic program that uses these effects. ```purescript data TalkF a = Speak String a | Listen (String -> a) type TALK r = (talk :: TalkF | r) _talk = Proxy :: Proxy "talk" speak :: forall r. String -> Run (TALK + r) Unit speak str = Run.lift _talk (Speak str unit) listen :: forall r. Run (TALK + r) String listen = Run.lift _talk (Listen identity) program :: forall r. Run (TALK + r) Unit program = do speak $ "Hello, what is your name?" name <- listen speak $ "Nice to meet you, " <> name ``` -------------------------------- ### PureScript DSL Combination: General Coproduct Source: https://github.com/natefaubion/purescript-run/blob/master/README.md A more general approach to combining DSLs using Coproduct, illustrating how to create a composite Functor type and lift operations. This method still involves manual lifting. ```purescript liftLeft :: forall f g. Free f ~> Free (Coproduct f g) liftLeft = hoistFree left liftRight :: forall f g. Free g ~> Free (Coproduct f g) liftRight = hoistFree right type LovelyEveningF = Coproduct TalkF DinnerF type LovelyEvening = Free LovelyEveningF dinnerTime :: LovelyEvening Unit dinnerTime = do liftLeft $ speak "I'm famished!" isThereMore <- liftRight $ eat Pizza if isThereMore then dinnerTime else do bill <- liftRight checkPlease liftLeft $ speak "Outrageous!" ``` -------------------------------- ### PureScript Free Monad DSL: Talk Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Defines a simple DSL for string input and output using the Free monad. Includes data type definition, type alias, and functions to lift DSL operations into the Free monad. ```purescript data TalkF a = Speak String a | Listen (String -> a) derive instance functorTalkF :: Functor TalkF type Talk = Free TalkF -- Boilerplate definitions for lifting our constructors -- into the Free DSL. speak :: String -> Talk Unit speak str = liftF (Speak str unit) listen :: Talk String listen = liftF (Listen identity) -- Now we can write programs using our DSL. program :: Talk Unit program = do speak $ "Hello, what is your name?" name <- listen speak $ "Nice to meet you, " <> name ``` -------------------------------- ### PureScript Talk Effect Interpreter Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Interprets the `TalkF` effect into the native `Effect` monad using `interpret` and `case_` for exhaustive pattern matching. It logs spoken messages to the console and provides a hardcoded reply for listening. ```purescript handleTalk :: TalkF ~> Effect handleTalk = case _ of Speak str next -> do Console.log str pure next Listen reply -> do pure (reply "I am Groot") main = program # interpret (case_ # on _talk handleTalk) ``` -------------------------------- ### PureScript Dinner Effect and Program Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Defines a `DinnerF` effect for eating food and checking the bill, then combines it with the `TalkF` effect into a `LovelyEvening` type. A program is created to simulate a dinner experience. ```purescript type DINNER r = (dinner :: DinnerF | r) _dinner :: Proxy :: Proxy "dinner" eat :: forall r. Food -> Run (DINNER + r) IsThereMore eat food = Run.lift _dinner (Eat food identity) checkPlease :: forall r. Run (DINNER + r) Bill checkPlease = Run.lift _dinner (CheckPlease identity) type LovelyEvening r = (TALK + DINNER + r) dinnerTime :: forall r. Run (LovelyEvening + r) Unit dinnerTime = do speak "I'm famished!" isThereMore <- eat Pizza if isThereMore then dinnerTime else do bill <- checkPlease speak "Outrageous!" ``` -------------------------------- ### PureScript Interpreting Talk into Effect Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Demonstrates interpreting the `TalkF` effect into `Run (EFFECT + r)` using `interpret` and `send`. This removes `TalkF` from the effect stack, replacing it with `EFFECT`, while leaving other effects like `DINNER` untouched. ```purescript -- This now interprets it back into `Run` but with the `EFFECT` effect. handleTalk :: forall r. TalkF ~> Run (EFFECT + r) handleTalk = case _ of Speak str next -> do -- `liftEffect` lifts native `Effect` effects into `Run`. liftEffect $ Console.log str pure next Listen reply -> do pure (reply "I am Groot") runTalk :: forall r . Run (EFFECT + TALK + r) ~> Run (EFFECT + r) runTalk = interpret (on _talk handleTalk send) program2 :: forall r. Run (EFFECT + DINNER + r) Unit program2 = dinnerTime # runTalk ``` -------------------------------- ### PureScript Running Base Effect Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Demonstrates how to extract a base `Effect` from a `Run` program. This is typically done when a program's effects have been fully interpreted down to raw `Effect` actions. ```PureScript program4 :: Effect (Tuple Bill Unit) program4 = runBaseEffect program3 ``` -------------------------------- ### PureScript Purely Interpreting Dinner with State Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Interprets the `DinnerF` effect purely using `runAccumPure`, managing internal state (stock and bill) to calculate the final bill. It returns the final bill along with the program's result. ```purescript type Tally = { stock :: Int, bill :: Bill } -- We have internal state, which is our running tally of the bill. handleDinner :: forall a. Tally -> DinnerF a -> Tuple Tally a handleDinner tally = case _ of Eat _ reply -- If we have food, bill the customer | tally.stock > 0 -> let tally' = { stock: tally.stock - 1, bill: tally.bill + 1 } in Tuple tally' (reply true) | otherwise -> Tuple tally (reply false) -- Reply with the bill CheckPlease reply -> Tuple tally (reply tally.bill) -- We eliminate the `DINNER` effect altogether, yielding the result -- together with the final bill. runDinnerPure :: forall r a. Tally -> Run (DINNER + r) a -> Run r (Tuple Bill a) runDinnerPure = runAccumPure (\tally -> on _dinner (Loop <<< handleDinner tally) Done) (\tally a -> Tuple tally.bill a) program3 :: forall r. Run (EFFECT + r) (Tuple Bill Unit) program3 = program2 # runDinnerPure { stock: 10, bill: 0 } ``` -------------------------------- ### PureScript Run Data Type Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Defines the `Run` newtype, which wraps a `Free (VariantF r) a`. This data type is central to the library's combinator zoo for writing interpreters. ```purescript newtype Run r a = Run (Free (VariantF r) a) ``` -------------------------------- ### PureScript Logging Effect Definition Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Defines a functor `LogF` for logging operations, a type alias `LOG` to represent the logging effect in a row, and a `log` function. The `log` function lifts a string message into the `Run` monad, tagged with the 'log' effect. ```PureScript data LogF a = Log String a derive instance functorLogF :: Functor LogF type LOG r = (log :: LogF | r) _log = Proxy :: Proxy "log" log :: forall r. String -> Run (LOG + r) Unit log str = Run.lift _log (Log str unit) ``` -------------------------------- ### PureScript Sleeping Effect Definition Source: https://github.com/natefaubion/purescript-run/blob/master/README.md Defines a functor `SleepF` for asynchronous sleeping operations, a type alias `SLEEP` for the sleeping effect, and a `sleep` function. The `sleep` function lifts a delay in milliseconds into the `Run` monad, tagged with the 'sleep' effect. ```PureScript data SleepF a = Sleep Int a derive instance functorSleepF :: Functor SleepF type SLEEP r = (sleep :: SleepF | r) _sleep = Proxy :: Proxy "sleep" sleep :: forall r. Int -> Run (SLEEP + r) Unit sleep ms = Run.lift _sleep (Sleep ms unit) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.