Application Structure


  • You should understand what "smart constructors" are (see Design Patterns folder) and how they work

The upcoming folders will explain

  • a small explanation on the onion architecture / 3-Layer Haskell Cake concepts
  • an overview of what MTL and Free/Run are and how they work conceptually
  • how to structure an FP program via MTL and Free/Run
  • folders starting with 1 contain heavily-commented examples of basic programs using these application architecture styles. When learning one particular style, you should look at these programs for what an 'end-result' looks like using that style as well as how it compares to other styles. We'll start with the simplest "hello world" program that uses only one effect and write programs that use more and more effects/capabilities.

These will later be used to write programs in the Projects folder that run in Node via the console and/or in the Browser via Halogen.

In the functional paradigm, programs are structured in such a way that they look very similar to something called the "onion architecture." The below videos are optional watching. Watch them for a clearer idea of what "onion architecture" is:

Another optional video to watch: Functional Architecture - The Pits of Success. It explains that FP naturally pushes developers towards this architecture whereas other languages push developers away from it.

When we structure our code according to the below table, it provides a number of benefits

  • top-down domain-driven design: your data types and your function's type signatures are often your always-up-to-date documentation
  • "impure" computations (i.e. computations that do things like state manipulation, reading from a file, network activities) are expressed as a "pure" computation, making them much easier to test
  • "Platforms" (i.e. frameworks, databases, etc.) can easily be swapped out with other newer platforms without changing any "business logic" code or potentially introducing regressions
Layer LevelOnion Architecture TermGeneral idea
Layer 4CoreStrong types with well-defined properties and their pure, total functions that operate on them
Layer 3Domainthe "business logic" code which uses "effects," impure computations that are expressed in a pure way
Layer 2APIthe "production" or "test" monad which "links" these pure effects/capabilties to their impure implementations
Layer 1Infrastructurethe platform-specific framework/libraries we'll use to implement some special effects/capabilities (i.e. Node.ReadLine (terminal-based programs), Halogen/React (web-based UIs))
Layer 0Machine Code
(no equivalent onion term)
the "base" monad that runs the program (e.g. production: Effect/Aff; test: Identity/Trampoline)

To get a general idea for the concept this folder is going to try to teach:

Another learning resource that is still a work-in-progress but which will explain more than this work is 'Functional Design and Architecture':

A Word of Thanks

While trying to learn this myself, I benefited from looking at the code in stepchownfun's BSD-3 licensed project, effects, as a guide when I did not completely understand something myself.