PureScript is a small strongly typed programming language that compiles to JavaScript.

PureScript Conf 2015

Learn about PureScript this summer at PureScript Conf 2015, colocated with LambdaConf 2015 in Boulder CO.


Modifying the DOM

PureScript’s expressive type system and lightweight syntax make it simple to define domain-specific languages, which can be used to solve problems like templating the DOM. Bindings also exist for libraries such as React and Angular.js.

import Data.DOM.Free
doc :: Element
doc = div [ _class := "image" ] $ do
  elem $ img [ src := "logo.jpg"
             , width  := 100
             , height := 200
  text "Functional programming for the web!"

HTML5 Canvas

Higher-order functions allow the developer to write fluent, expressive code. Here, higher-order functions are being used to capture some common patterns when working with HTML5 canvas, such as saving and restoring the context and drawing closed paths.

import Control.Apply

import Graphics.Canvas (getCanvasElementById, getContext2D)
import Graphics.Canvas.Free

closed path = beginPath *> path <* closePath

filled shape = shape <* fill

withContext shape = save *> shape <* restore

scene :: Graphics Unit
scene = withContext do
  setFillStyle "#FF0000"

  filled $ closed do
    moveTo 0 0
    lineTo 50 0
    lineTo 25 50

main = do
  canvas <- getCanvasElementById "canvas"
  context <- getContext2D canvas

  runGraphics context scene

Callback Hell

The problem of callback hell can be solved by using PureScript’s type system to capture complex control flow as functions in a safe way. Here, the continuation monad is used to hide the boilerplate code associated with handling callbacks.

import DOM
import Control.Monad.Eff
import Control.Monad.Cont.Trans

type App = Eff (dom :: DOM, ajax :: AJAX)

data Model = Model [Product] [ProductCategory]

loadModel :: ContT Unit App Model
loadModel = do
  model <- runParallel $
    Model <$> Parallel (get "/products/popular/")
          <*> Parallel (get "/categories/all")

view :: Model -> App Unit
view (Model ps cs) = do
  renderProducts ps
  renderCategories cs

main :: App Unit
main = loadModel `runContT` view

Generative Testing

PureScript provides a form of ad-hoc polymorphism in the form of type classes, inspired by Haskell. Type classes are used in the QuickCheck and StrongCheck libraries to support generative testing, which separates test definitions from the generation of test cases.

import Test.QuickCheck

main = do
  quickCheck $ \xs ys ->
    isSorted $ merge (sort xs) (sort ys)
  quickCheck $ \xs ys ->
    xs `isSubarrayOf` merge xs ys