Data Visualization Purescript Front-end

The front-end is written in PureScript; I renamed source files from *.purs to *.hs to get online syntax highlighting.

Brief PureScript Introduction

PureScript is very similar to Haskell, but differs in several aspects. It is strict, and uses a somewhat different typeclass hierarchy and naming. Notably

  • Effect is equivalent to Haskell IO. For example, console.log has type String -> Effect Unit (docs)
  • Aff is an asynchronous effect monad. For example, an AJAX request would return Aff (Either Error ResponseType) (docs).
  • Functions can be found on Pursuit which is similar to Hoogle.
    • # is flip ($)
    • <#> is flip <$>
    • Unit is ()
  • Record access/update syntax is different but hopefully comprehensible.

PureScript also heavily encourages writing total functions. For example, an array indexing function returns Maybe a. For partial indexing, one must use unsafeIndex together with unsafePartial - quite a bunch of loops to jump through. This repo doesn't use any partial functions.

Application Introduction

The application serves for data visualization purposes. Data is served by a Rust back-end from a database; the front-end uses several simple GET endpoints to get the data. The website is made using the Halogen library; it is single-page, and includes proper routing. I made a screenshot for illustration.

Since this is a simple application, I didn't bother with any sort of effect management; everything effectful is in the Effect or Aff monad. If the application were to grow more, I would probably go for the "three-layered cake" architecture with a ReaderT Env Effect at the bottom.

Also, error handling is crude. For example, most remotely-fetched state is inside Maybe, but this doesn't represent errors in any way. They are simply written out to console instead. I just couldn't be bothered to do it properly :)

Here are some interesting files:

  • Types.hs - Data types and their JSON deserialization
  • Filtering.hs - Elm-like model-view-update component architecture. This is the page in the screenshot above.
  • Filter.hs - A simple LL(0) parser combinator for trajectory filtering.
  • Api.hs - GET request generation