Context in PureScript

Here’s the translation of the Go code to PureScript, along with explanations in Markdown format suitable for Hugo:

In this example, we'll demonstrate how to create a simple HTTP server in PureScript and use the concept of cancellation, which is similar to Go's `context.Context`. We'll use the `Aff` monad for asynchronous effects and the `purescript-node-http` library for creating an HTTP server.

First, let's import the necessary modules:

```purescript
module Main where

import Prelude

import Effect (Effect)
import Effect.Aff (Aff, launchAff_, delay, race)
import Effect.Class (liftEffect)
import Effect.Console (log)
import Node.HTTP as HTTP
import Node.HTTP.Client as Client
import Data.Either (Either(..))
import Data.Time.Duration (Milliseconds(..))

Now, let’s define our hello handler function:

hello :: HTTP.Request -> HTTP.Response -> Aff Unit
hello req res = do
  liftEffect $ log "server: hello handler started"
  result <- race (delay (Milliseconds 10000.0)) (pure unit)
  case result of
    Left _ -> 
      liftEffect $ do
        log "server: request completed"
        HTTP.setStatusCode res 200
        HTTP.setHeader res "Content-Type" "text/plain"
        HTTP.write res "hello\n"
        HTTP.end res
    Right _ -> 
      liftEffect $ do
        log "server: request cancelled"
        HTTP.setStatusCode res 500
        HTTP.setHeader res "Content-Type" "text/plain"
        HTTP.write res "Internal Server Error\n"
        HTTP.end res
  liftEffect $ log "server: hello handler ended"

In this handler, we simulate some work by waiting for 10 seconds. We use the race function to compete between the delay and an immediate completion. If the delay wins, we send a successful response. If the immediate completion wins (simulating cancellation), we send an error response.

Now, let’s set up our main function to create and start the server:

main :: Effect Unit
main = launchAff_ do
  server <- liftEffect $ HTTP.createServer $ \req res -> launchAff_ $ hello req res
  liftEffect $ HTTP.listen server { hostname: "localhost", port: 8090 } $ 
    log "Server listening on http://localhost:8090"

To run this server, you would compile the PureScript code and run it with Node.js. Here’s how you might interact with it:

$ spago run
Server listening on http://localhost:8090

# In another terminal:
$ curl http://localhost:8090/hello
# (Wait for 10 seconds)
hello

# If you cancel the request before 10 seconds (e.g., with Ctrl+C):
$ curl http://localhost:8090/hello
^C

In the server logs, you would see:

server: hello handler started
server: request completed
server: hello handler ended

Or if cancelled:

server: hello handler started
server: request cancelled
server: hello handler ended

This example demonstrates how to handle long-running requests and potential cancellations in PureScript, similar to the concept of context in the original example. The Aff monad provides a way to work with asynchronous effects and handle cancellation, which is conceptually similar to Go’s context package.