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!"
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
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
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
- Algebraic data types
- Pattern matching
- Type inference
- Type classes
- Higher kinded types
- Rank-N types
- Extensible records
- Extensible effects
- Simple FFI
- No runtime system
- Human-readable output