Effects, functionally
What are functional effects, really?
Functional effects can be used to model side effects in a purely functional program. When we think about what side effects are in a non-pure program we can say that they are all the other things that can happen besides passing around a value. Functional effects are a functional way to keep this separation of the effect and passing around a value.
Functional effects consist of:
- a polymorphic data type that separates the value from the effect
- combinators on that data type that allow you to work with the value without having to deal with the effect
Let’s look at some examples (from PureScript):
Partiality
data Maybe a = Nothing | Just a
- Separates the value
a
from the effect of partiality enabled by theNothing
constructor - Effect: partiality, being able to short circuit a computation, nondeterministic choice
- Useful combinators:
bind
,apply
,alt
Read-only context
data Reader r a = Reader (r -> a)
- Separates the value
a
from the effect of reading a valuer
from the context - Effect: access to a value inside the computation, a “global value” so to speak
- Useful combinators:
bind
,apply
,ask
,local
Read-write context
data State s a = State (s -> Tuple a s)
- Separates the value
a
from the effect of states
- Effect: access to a read-write context within the computation
- Useful combinators:
bind
,apply
,put
,modify
No effects
data Identity a = Identity a
- Separates the value
a
from the “null” effect. A surprisingly useful data type that can be used in places where no effects are needed. - Effect: none
- Useful combinators:
bind
,apply
,alt
, and many others