Overview
There are type classes that control the flow of the program (e.g. whether the program should do X and then Y or should do X and Y at the same time).
Functor, Apply, and Bind Type Classes Explained in Pictures
We've linked to an article below that explains these abstract notions in a clear manner using pictures and the Maybe a
data structure. However, since these concepts are explained in Haskell, which uses different terminology than Purescript, use the following table to map
Haskell terminology to Purescript terminology:
Haskell Terminology | Purescript Terminology |
---|---|
fmap (function) | map (function) |
Applicative (type class) | Apply (type class) |
Array /[] (syntax sugar for List a ) | List a |
map (Array function) | see the implementation in Purescript |
IO () | Effect Unit , which will be explained/used in a later part of this folder |
Here's the link: Functors, Applicatives, and Monads in Pictures
Lists' Map Function in Purescript
Here's the map
List function implemented in Purescript:
data List a = Nil | Cons a (List a)
instance Functor List where
map :: forall a b. (a -> b) -> List a -> List b
map f Nil = Nil
map f (Cons head tail) = Cons (f head) (map f tail)
Functor, Apply, Applicative, Bind, Monad
In Short
Concept | Argument is NOT inside a Box / context | Argument is inside a Box / context | Name |
---|---|---|---|
1-arg function application | function arg | function <$> (Box arg) | Functor |
2+-arg function application | function arg1 arg2 | function <$> (Box arg1) <*> (Box arg2) | Applicative |
function composition | aToB >>> bToC | aToBoxB >=> bToBoxC | Monad |
Somewhat longer
These will be covered at a slower and clearer pace in the upcoming files. This is just an overview of them.
Typeclass | "Plain English" | Function | Infix | Laws | Usage |
---|---|---|---|---|---|
Functor | Mappable | map :: forall a b. (a -> b) -> f a -> f b | <$> (Left 4) |
| Change a value, a , that's currently stored in some box-like type, f , using a function, (a -> b) |
Apply | Boxed Mappable | apply :: forall a b. f (a -> b) -> f a -> f b | <*> (Left 4) |
| Same as Functor except the function is now inside of the same box-like type. |
Applicative | Liftable Parallel Computation | pure :: forall a. a -> f a |
| Put a value into a box Run code in parallel | |
Bind | Sequential Computation | bind :: forall m a b. m a -> (a -> m b) -> m b | >>= (Left 1) | Associativity: (x >>= f) >>= g == x >>= (\x' -> f x' >>= g) | Given an value of a box-like type, m , that contains a value, a , extract the a from m , and create a new m value that stores a new value, b . Take m a and compute it via bind />>= to produce a value, a . Then, use a to describe (but not run) a new computation, m b . When m b is computed (via a later bind />>= ), it will return b . |
Monad | FP Program |
| The data structure used to run FP programs by executing code line-by-line, function-by-function, etc. |
Simplest Monad Implementation
data Box a = Box a
instance Functor Box where
map f (Box a) = Box (f a)
instance Apply Box where
apply (Box f) (Box a) = Box (f a)
instance Bind Box where
bind (Box a) f = f a
instance Applicative Box where
pure a = Box a
instance Monad Box
Function Reduction
In these files, we will "evaluate" functions by using graph reductions: replacing the left-hand side (LHS) of the =
sign (the function's call signature) with the right-hand side (RHS) of the =
sign (the function's implementation / body). In other words...
someFunction arg1 arg2 arg3 = bodyOfFunction
| call signature (LHS) | = | body (RHS) |