intern-resources/readme.md
2023-10-06 18:45:48 -05:00

3.0 KiB

thunderstrike.ai intern resources

purescript

Purescript is a strongly-typed [type safety] purely functional [purely functional] programming language that compiles to javascript (like typescript).

In brief

  • effectful code [side effect] is isolated from non-effectful code. This makes programs much more consistent to run and reason about.
  • everything is an expression
  • interacting with raw javascript is relatively painless

Motivating example: React vs Halogen

You don't have to understand exactly how these examples work, I'm providing them simply for you to glance over and get a feeling for reading typescript/javascript vs purescript.

This app:

  1. renders "Loading..." until either data or error
  2. fetches data from a server
  3. if ok, render items in a list. if error, render error span at the bottom of the page.
React (click to expand)
type Item = {id: string, title: string, description: string}

export const App: () => React.Node = () => {
  const [items, setItems] = React.useState<Array<Item> | undefined>(undefined)
  const [error, setError] = React.useState<Error | undefined>(undefined)

  React.useEffect(() => {
    fetch('/api/item')
      .then(rep => rep.json<Array<Item>>())
      .then(items => setItems(items))
      .catch(e => setError(e))
  }, [])

  return error !== undefined
    ? (<p class="error">{error.message}</p>)
    : items === undefined
    ? (<p>Loading...</p>)
    : items.map(item => {
        return (
          <div key={item.id}>
            <p>{item.title}</p>
            <span class="small">
              {item.description}
            </span>
          </div>
        )
      })
}
Purescript Halogen (click to expand)
type Item = { id :: String, title :: String, description :: String }

data State
  = StateEmpty
  | StateErrored Error
  | StateGotItems (Array Item)

data Action = ActionInit

renderItem item = div [] [ p [] [text item.title]
                         , span
                             [className "small"]
                             [text item.description]
                         ]

renderApp StateEmpty = p [] [text "Loading..."]
renderApp (StateErrored e) = p [className "error"] [text (message e)]
renderApp (StateGotItems items) = map renderItem items

action ActionInit = do
  response <- fetch (URL "/api/item") {method: Get}
  jsonString <- text response
  itemsOrError <- readJSON jsonString
  case itemsOrError of
    Right items -> put (StateGotItems items)
    Left error -> put (StateErrored error)

app = mkComponent
  { initialState: StateEmpty
  , render: renderApp
  , eval: mkEval ( defaultEval { handleAction = action, initialize: Just ActionInit } )
  }