# 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]https://www.purescript.org/ 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]https://pursuit.purescript.org/packages/purescript-console/4.4.0/docs/Effect.Console#v:log)
* `Aff` is an asynchronous effect monad. For example, an AJAX request would return `Aff (Either Error ResponseType)` ([docs]https://pursuit.purescript.org/packages/purescript-affjax/11.0.0/docs/Affjax#v:get).
* Functions can be found on [Pursuit]https://pursuit.purescript.org/ 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]https://pursuit.purescript.org/packages/purescript-arrays/5.3.1/docs/Data.Array#v:(!!) returns `Maybe a`. For partial indexing, one must use [`unsafeIndex`]https://pursuit.purescript.org/packages/purescript-arrays/5.3.1/docs/Data.Array#v:unsafeIndex together with [`unsafePartial`]https://pursuit.purescript.org/packages/purescript-partial/2.0.1/docs/Partial.Unsafe#v: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]https://imgur.com/a/3YxVW9y 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]https://nest.pijul.com/potocpav/frontend:main/A4YPCXNG44HRK.IUMAA - Data types and their JSON deserialization
* [Filtering.hs]https://nest.pijul.com/potocpav/frontend:main/A4YPCXNG44HRK.VWSQA - Elm-like model-view-update component architecture. This is the page in the screenshot above.
* [Filter.hs]https://nest.pijul.com/potocpav/frontend:main/A4YPCXNG44HRK.YQ3QA - A simple LL(0) parser combinator for trajectory filtering.
* [Api.hs]https://nest.pijul.com/potocpav/frontend:main/A4YPCXNG44HRK.R35AA - GET request generation