Skip to content

Commit ef4f1d1

Browse files
committed
Version 1.0.0
1 parent b15c1f5 commit ef4f1d1

File tree

2 files changed

+317
-1
lines changed

2 files changed

+317
-1
lines changed

README.md

Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
<a href="https://github.com/fantasyland/fantasy-land"><img alt="Fantasy Land" src="https://raw.githubusercontent.com/fantasyland/fantasy-land/master/logo.png" width="75" height="75" align="left"></a>
2+
3+
# sanctuary-either
4+
5+
The Either type represents values with two possibilities: a value of type
6+
`Either a b` is either a Left whose value is of type `a` or a Right whose
7+
value is of type `b`.
8+
9+
`Either a b` satisfies the following [Fantasy Land][] specifications:
10+
11+
```javascript
12+
> const Useless = require ('sanctuary-useless')
13+
14+
> S.map (k => k + ' '.repeat (16 - k.length) +
15+
. (Z[k].test (Right (Useless)) ? '\u2705 ' :
16+
. Z[k].test (Right (['foo'])) ? '\u2705 * ' :
17+
. /* otherwise */ '\u274C '))
18+
. (S.keys (Z.filter ($.test ([]) ($.TypeClass), Z)))
19+
[ 'Setoid ✅ * ', // if ‘a’ and ‘b’ satisfy Setoid
20+
. 'Ord ✅ * ', // if ‘a’ and ‘b’ satisfy Ord
21+
. 'Semigroupoid ❌ ',
22+
. 'Category ❌ ',
23+
. 'Semigroup ✅ * ', // if ‘a’ and ‘b’ satisfy Semigroup
24+
. 'Monoid ❌ ',
25+
. 'Group ❌ ',
26+
. 'Filterable ❌ ',
27+
. 'Functor ✅ ',
28+
. 'Bifunctor ✅ ',
29+
. 'Profunctor ❌ ',
30+
. 'Apply ✅ ',
31+
. 'Applicative ✅ ',
32+
. 'Chain ✅ ',
33+
. 'ChainRec ✅ ',
34+
. 'Monad ✅ ',
35+
. 'Alt ✅ ',
36+
. 'Plus ❌ ',
37+
. 'Alternative ❌ ',
38+
. 'Foldable ✅ ',
39+
. 'Traversable ✅ ',
40+
. 'Extend ✅ ',
41+
. 'Comonad ❌ ',
42+
. 'Contravariant ❌ ' ]
43+
```
44+
45+
#### <a name="Either" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L138">`Either :: TypeRep Either`</a>
46+
47+
Either [type representative][].
48+
49+
#### <a name="Either.Left" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L142">`Either.Left :: a -⁠> Either a b`</a>
50+
51+
Constructs a value of type `Either a b` from a value of type `a`.
52+
53+
```javascript
54+
> Left ('sqrt undefined for -1')
55+
Left ('sqrt undefined for -1')
56+
```
57+
58+
#### <a name="Either.Right" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L165">`Either.Right :: b -⁠> Either a b`</a>
59+
60+
Constructs a value of type `Either a b` from a value of type `b`.
61+
62+
```javascript
63+
> Right (42)
64+
Right (42)
65+
```
66+
67+
#### <a name="Either.@@type" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L188">`Either.@@type :: String`</a>
68+
69+
Either [type identifier][].
70+
71+
```javascript
72+
> type (Right (42))
73+
'sanctuary-either/Either@1'
74+
75+
> type.parse (type (Right (42)))
76+
{namespace: 'sanctuary-either', name: 'Either', version: 1}
77+
```
78+
79+
#### <a name="Either.fantasy-land/of" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L201">`Either.fantasy-land/of :: b -⁠> Either a b`</a>
80+
81+
- `of (Either) (x)` is equivalent to `Right (x)`
82+
83+
```javascript
84+
> S.of (Either) (42)
85+
Right (42)
86+
```
87+
88+
#### <a name="Either.fantasy-land/chainRec" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L214">`Either.fantasy-land/chainRec :: ((a -⁠> c, b -⁠> c, a) -⁠> Either d c, a) -⁠> Either d b`</a>
89+
90+
```javascript
91+
> Z.chainRec (
92+
. Either,
93+
. (next, done, x) =>
94+
. x <= 1 ? Left ('!!') : Right (x >= 1000 ? done (x) : next (x * x)),
95+
. 1
96+
. )
97+
Left ('!!')
98+
99+
> Z.chainRec (
100+
. Either,
101+
. (next, done, x) =>
102+
. x <= 1 ? Left ('!!') : Right (x >= 1000 ? done (x) : next (x * x)),
103+
. 2
104+
. )
105+
Right (65536)
106+
```
107+
108+
#### <a name="Either.prototype.@@show" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L243">`Either#@@show :: (Showable a, Showable b) => Either a b ~> () -⁠> String`</a>
109+
110+
- `show (Left (x))` is equivalent to `'Left (' + show (x) + ')'`
111+
- `show (Right (x))` is equivalent to `'Right (' + show (x) + ')'`
112+
113+
```javascript
114+
> show (Left ('sqrt undefined for -1'))
115+
'Left ("sqrt undefined for -1")'
116+
117+
> show (Right ([1, 2, 3]))
118+
'Right ([1, 2, 3])'
119+
```
120+
121+
#### <a name="Either.prototype.fantasy-land/equals" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L262">`Either#fantasy-land/equals :: (Setoid a, Setoid b) => Either a b ~> Either a b -⁠> Boolean`</a>
122+
123+
- `Left (x)` is equal to `Left (y)` [iff][] `x` is equal to `y`
124+
according to [`Z.equals`][]
125+
- `Right (x)` is equal to `Right (y)` [iff][] `x` is equal to `y`
126+
according to [`Z.equals`][]
127+
- `Left (x)` is never equal to `Right (y)`
128+
129+
```javascript
130+
> S.equals (Left ([1, 2, 3])) (Left ([1, 2, 3]))
131+
true
132+
133+
> S.equals (Right ([1, 2, 3])) (Right ([1, 2, 3]))
134+
true
135+
136+
> S.equals (Left ([1, 2, 3])) (Right ([1, 2, 3]))
137+
false
138+
```
139+
140+
#### <a name="Either.prototype.fantasy-land/lte" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L287">`Either#fantasy-land/lte :: (Ord a, Ord b) => Either a b ~> Either a b -⁠> Boolean`</a>
141+
142+
- `Left (x)` is less than or equal to `Left (y)` [iff][] `x` is less
143+
than or equal to `y` according to [`Z.lte`][]
144+
- `Right (x)` is less than or equal to `Right (y)` [iff][] `x` is less
145+
than or equal to `y` according to [`Z.lte`][]
146+
- `Left (x)` is always less than `Right (y)`
147+
148+
```javascript
149+
> S.filter (S.lte (Left (1))) ([Left (0), Left (1), Left (2)])
150+
[Left (0), Left (1)]
151+
152+
> S.filter (S.lte (Right (1))) ([Right (0), Right (1), Right (2)])
153+
[Right (0), Right (1)]
154+
155+
> S.filter (S.lte (Left (1))) ([Right (0), Right (1), Right (2)])
156+
[]
157+
158+
> S.filter (S.lte (Right (1))) ([Left (0), Left (1), Left (2)])
159+
[Left (0), Left (1), Left (2)]
160+
```
161+
162+
#### <a name="Either.prototype.fantasy-land/concat" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L315">`Either#fantasy-land/concat :: (Semigroup a, Semigroup b) => Either a b ~> Either a b -⁠> Either a b`</a>
163+
164+
- `concat (Left (x)) (Left (y))` is equivalent to
165+
`Left (concat (x) (y))`
166+
- `concat (Right (x)) (Right (y))` is equivalent to
167+
`Right (concat (x) (y))`
168+
- `concat (Left (x)) (Right (y))` is equivalent to `Right (y)`
169+
- `concat (Right (x)) (Left (y))` is equivalent to `Right (x)`
170+
171+
```javascript
172+
> S.concat (Left ('abc')) (Left ('def'))
173+
Left ('abcdef')
174+
175+
> S.concat (Right ([1, 2, 3])) (Right ([4, 5, 6]))
176+
Right ([1, 2, 3, 4, 5, 6])
177+
178+
> S.concat (Left ('abc')) (Right ([1, 2, 3]))
179+
Right ([1, 2, 3])
180+
181+
> S.concat (Right ([1, 2, 3])) (Left ('abc'))
182+
Right ([1, 2, 3])
183+
```
184+
185+
#### <a name="Either.prototype.fantasy-land/map" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L344">`Either#fantasy-land/map :: Either a b ~> (b -⁠> c) -⁠> Either a c`</a>
186+
187+
- `map (f) (Left (x))` is equivalent to `Left (x)`
188+
- `map (f) (Right (x))` is equivalent to `Right (f (x))`
189+
190+
```javascript
191+
> S.map (S.add (1)) (Left ('sqrt undefined for -1'))
192+
Left ('sqrt undefined for -1')
193+
194+
> S.map (S.add (1)) (Right (99))
195+
Right (100)
196+
```
197+
198+
#### <a name="Either.prototype.fantasy-land/bimap" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L363">`Either#fantasy-land/bimap :: Either a c ~> (a -⁠> b, c -⁠> d) -⁠> Either b d`</a>
199+
200+
- `bimap (f) (g) (Left (x))` is equivalent to `Left (f (x))`
201+
- `bimap (f) (g) (Right (x))` is equivalent to `Right (g (x))`
202+
203+
```javascript
204+
> S.bimap (S.toUpper) (S.add (1)) (Left ('abc'))
205+
Left ('ABC')
206+
207+
> S.bimap (S.toUpper) (S.add (1)) (Right (99))
208+
Right (100)
209+
```
210+
211+
#### <a name="Either.prototype.fantasy-land/ap" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L382">`Either#fantasy-land/ap :: Either a b ~> Either a (b -⁠> c) -⁠> Either a c`</a>
212+
213+
- `ap (Left (x)) (Left (y))` is equivalent to `Left (x)`
214+
- `ap (Left (x)) (Right (y))` is equivalent to `Left (x)`
215+
- `ap (Right (f)) (Left (x))` is equivalent to `Left (x)`
216+
- `ap (Right (f)) (Right (x))` is equivalent to `Right (f (x))`
217+
218+
```javascript
219+
> S.ap (Left ('div undefined for 0')) (Left ('sqrt undefined for -1'))
220+
Left ('div undefined for 0')
221+
222+
> S.ap (Left ('div undefined for 0')) (Right (99))
223+
Left ('div undefined for 0')
224+
225+
> S.ap (Right (S.add (1))) (Left ('sqrt undefined for -1'))
226+
Left ('sqrt undefined for -1')
227+
228+
> S.ap (Right (S.add (1))) (Right (99))
229+
Right (100)
230+
```
231+
232+
#### <a name="Either.prototype.fantasy-land/chain" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L409">`Either#fantasy-land/chain :: Either a b ~> (b -⁠> Either a c) -⁠> Either a c`</a>
233+
234+
- `chain (f) (Left (x))` is equivalent to `Left (x)`
235+
- `chain (f) (Right (x))` is equivalent to `f (x)`
236+
237+
```javascript
238+
> const sqrt = n => n < 0 ? Left ('sqrt undefined for ' + show (n))
239+
. : Right (Math.sqrt (n))
240+
241+
> S.chain (sqrt) (Left ('div undefined for 0'))
242+
Left ('div undefined for 0')
243+
244+
> S.chain (sqrt) (Right (-1))
245+
Left ('sqrt undefined for -1')
246+
247+
> S.chain (sqrt) (Right (25))
248+
Right (5)
249+
```
250+
251+
#### <a name="Either.prototype.fantasy-land/alt" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L434">`Either#fantasy-land/alt :: Either a b ~> Either a b -⁠> Either a b`</a>
252+
253+
- `alt (Left (x)) (Left (y))` is equivalent to `Left (y)`
254+
- `alt (Left (x)) (Right (y))` is equivalent to `Right (y)`
255+
- `alt (Right (x)) (Left (y))` is equivalent to `Right (x)`
256+
- `alt (Right (x)) (Right (y))` is equivalent to `Right (x)`
257+
258+
```javascript
259+
> S.alt (Left ('A')) (Left ('B'))
260+
Left ('B')
261+
262+
> S.alt (Left ('C')) (Right (1))
263+
Right (1)
264+
265+
> S.alt (Right (2)) (Left ('D'))
266+
Right (2)
267+
268+
> S.alt (Right (3)) (Right (4))
269+
Right (3)
270+
```
271+
272+
#### <a name="Either.prototype.fantasy-land/reduce" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L461">`Either#fantasy-land/reduce :: Either a b ~> ((c, b) -⁠> c, c) -⁠> c`</a>
273+
274+
- `reduce (f) (x) (Left (y))` is equivalent to `x`
275+
- `reduce (f) (x) (Right (y))` is equivalent to `f (x) (y)`
276+
277+
```javascript
278+
> S.reduce (S.concat) ([1]) (Left ('sqrt undefined for -1'))
279+
[1]
280+
281+
> S.reduce (S.concat) ([1]) (Right ([2]))
282+
[1, 2]
283+
```
284+
285+
#### <a name="Either.prototype.fantasy-land/traverse" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L480">`Either#fantasy-land/traverse :: Applicative f => Either a b ~> (TypeRep f, b -⁠> f c) -⁠> f (Either a c)`</a>
286+
287+
- `traverse (A) (f) (Left (x))` is equivalent to `of (A) (Left (x))`
288+
- `traverse (A) (f) (Right (x))` is equivalent to `map (Right) (f (x))`
289+
290+
```javascript
291+
> S.traverse (Array) (S.words) (Left ('sqrt undefined for -1'))
292+
[Left ('sqrt undefined for -1')]
293+
294+
> S.traverse (Array) (S.words) (Right ('foo bar baz'))
295+
[Right ('foo'), Right ('bar'), Right ('baz')]
296+
```
297+
298+
#### <a name="Either.prototype.fantasy-land/extend" href="https://github.com/sanctuary-js/sanctuary-either/blob/v1.0.0/index.js#L499">`Either#fantasy-land/extend :: Either a b ~> (Either a b -⁠> c) -⁠> Either a c`</a>
299+
300+
- `extend (f) (Left (x))` is equivalent to `Left (x)`
301+
- `extend (f) (Right (x))` is equivalent to `Right (f (Right (x)))`
302+
303+
```javascript
304+
> S.extend (S.reduce (S.add) (1)) (Left ('sqrt undefined for -1'))
305+
Left ('sqrt undefined for -1')
306+
307+
> S.extend (S.reduce (S.add) (1)) (Right (99))
308+
Right (100)
309+
```
310+
311+
[Fantasy Land]: https://github.com/fantasyland/fantasy-land/tree/v3.5.0
312+
[`Z.equals`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#equals
313+
[`Z.lte`]: https://github.com/sanctuary-js/sanctuary-type-classes/tree/v9.0.0#lte
314+
[iff]: https://en.wikipedia.org/wiki/If_and_only_if
315+
[type identifier]: https://github.com/sanctuary-js/sanctuary-type-identifiers/tree/v2.0.1
316+
[type representative]: https://github.com/fantasyland/fantasy-land/tree/v3.5.0#type-representatives

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sanctuary-either",
3-
"version": "0.0.0",
3+
"version": "1.0.0",
44
"description": "Fantasy Land -compliant Either type",
55
"license": "MIT",
66
"repository": {

0 commit comments

Comments
 (0)