@@ -13,4 +13,157 @@ bower install purescript-effect
1313
1414## Documentation
1515
16+ Values in PureScript do not have side-effects by default. This package provides
17+ the standard type PureScript uses to handle "native" effects, i.e. effects
18+ which are provided by the runtime system, and which cannot be emulated by pure
19+ functions. Some examples of native effects are:
20+
21+ * Console IO
22+ * Random number generation
23+ * Exceptions
24+ * Reading/writing mutable state
25+
26+ And in the browser:
27+
28+ * DOM manipulation
29+ * XMLHttpRequest / AJAX calls
30+ * Interacting with a websocket
31+ * Writing/reading to/from local storage
32+
33+ All of these things may be represented in PureScript by the ` Effect ` type.
34+ A value of the type ` Effect a ` represents a computation which may perform
35+ some native effects, and which produces a value of the type ` a ` once it
36+ finishes. For example, the module ` Effect.Random ` from ` purescript-random `
37+ exports a value ` random ` , whose type is ` Effect Number ` . When run, this
38+ effect produces a random number between 0 and 1. To give another example,
39+ the module ` Effect.Console ` exports a function ` log ` , whose type is
40+ ` String -> Effect Unit ` . This function takes a string and produces an
41+ effect which, when run, prints the provided string to the console.
42+
43+ ``` purescript
44+ module RandomExample where
45+ import Prelude
46+ import Effect (Effect)
47+ import Effect.Random (random)
48+ import Effect.Console (log)
49+
50+ printRandom :: Effect Unit
51+ printRandom = do
52+ n <- random
53+ log (show n)
54+ ```
55+
56+ In this example, ` printRandom ` is an effect which generates a random
57+ number between 0 and 1 and prints it to the console. You can test it out
58+ in the repl:
59+
60+ ```
61+ > import RandomExample
62+ > printRandom
63+ 0.71831842260513870
64+ unit
65+ ```
66+
67+ The ` unit ` is there because all effects must produce a value. When there
68+ is nothing useful to return, we usually use the type ` Unit ` , which has
69+ just one value: ` unit ` .
70+
71+ ### Effects and Purity
72+
73+ Note that using ` Effect ` does not compromise the purity of your program.
74+ Functions which make use of ` Effect ` are still pure, in the sense that
75+ all functions will return the same outputs given the same inputs.
76+
77+ This is enabled by having the ` Effect ` type denote _ values_ which can be
78+ run to produce native effects; an ` Effect a ` is a computation which has
79+ not yet necessarily been performed. In fact, there is no way of "running"
80+ an ` Effect ` manually; we cannot provide a (safe) function of the type
81+ ` forall a. Effect a -> a ` , because such a function would violate purity;
82+ it could produce different outputs given the same input. (Note that there
83+ is actually such a function in the module ` Effect.Unsafe ` , but it is best
84+ avoided outside of exceptional circumstances.)
85+
86+ Instead, the recommended way of "running" an effect is to include it as
87+ part of your program's ` main ` value.
88+
89+ A consequence of being able to represent native effects purely using
90+ ` Effect ` is that you can construct and pass ` Effect ` values around your
91+ programs freely. For example, we can write functions which can decide
92+ whether to run a given effect just once, many times, or not at all:
93+
94+ ``` purescript
95+ -- | Runs an effect three times, provided that the given condition is
96+ -- | true.
97+ thriceIf :: Boolean -> Effect Unit -> Effect Unit
98+ thriceIf cond effect =
99+ if cond
100+ then do
101+ effect
102+ effect
103+ effect
104+ else
105+ pure unit
106+ ```
107+
108+ ### Using Effects via the Foreign Function Interface
109+
110+ A computation of type ` Effect a ` is implemented in JavaScript as a
111+ zero-argument function whose body is expected to perform its side-effects
112+ before finally returning its result. For example, suppose we wanted a
113+ computation which would increment a global counter and return the new
114+ result each time it was run. We can implement this as follows:
115+
116+ ``` purescript
117+ -- Counter.purs
118+ foreign import incrCounter :: Effect Int
119+ ```
120+
121+ and in the corresponding JavaScript module:
122+
123+ ``` javascript
124+ // Counter.js
125+ exports .incrCounter = function () {
126+ if (! window .globalCounter ) {
127+ window .globalCounter = 0 ;
128+ }
129+ return ++ window .globalCounter ;
130+ }
131+ ```
132+
133+ For more information about the FFI (Foreign Function Interface), see
134+ the [ documentation repository] ( https://github.com/purescript/documentation ) .
135+ This package also provides a module
136+ [ Effect.Uncurried] ( https://pursuit.purescript.org/packages/purescript-effect/docs/Effect.Uncurried )
137+ to simplify the process of making uncurried effectful JavaScript functions
138+ available to PureScript via the FFI.
139+
140+ ### The Effect type is Magic
141+
142+ The PureScript compiler has special support for the ` Effect ` monad.
143+ Ordinarily, a chain of monadic binds might result in poor performance when
144+ executed. However, the compiler can generate code for the ` Effect ` monad
145+ without explicit calls to the monadic bind function ` >>= ` .
146+
147+ Take the random number generation example from above. When compiled, the
148+ compiler produces the following JavaScript:
149+
150+ ``` javascript
151+ var printRandom = function __do () {
152+ var $0 = Effect_Random .random ();
153+ return Effect_Console .log (Data_Show .show (Data_Show .showNumber )($0))();
154+ };
155+ ```
156+
157+ whereas a more naive compiler might, for instance, produce:
158+ ``` javascript
159+ var printRandom = Control_Bind .bind (Effect .bindEffect )(Effect_Random .random )(function ($0 ) {
160+ return Effect_Console .log (Data_Show .show (Data_Show .showNumber )($0));
161+ });
162+ ```
163+
164+ While this is a small improvement, the benefit is greater when using
165+ multiple nested calls to ` >>= ` .
166+
167+ ### API reference
168+
16169Module documentation is [ published on Pursuit] ( http://pursuit.purescript.org/packages/purescript-effect ) .
0 commit comments