1 | # # The Identity container
|
2 |
|
3 | /** ^
|
4 | * Copyright (c) 2013 Quildreen "Sorella" Motta <quildreen@gmail.com>
|
5 | *
|
6 | * Permission is hereby granted, free of charge, to any person
|
7 | * obtaining a copy of this software and associated documentation files
|
8 | * (the "Software"), to deal in the Software without restriction,
|
9 | * including without limitation the rights to use, copy, modify, merge,
|
10 | * publish, distribute, sublicense, and/or sell copies of the Software,
|
11 | * and to permit persons to whom the Software is furnished to do so,
|
12 | * subject to the following conditions:
|
13 | *
|
14 | * The above copyright notice and this permission notice shall be
|
15 | * included in all copies or substantial portions of the Software.
|
16 | *
|
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24 | */
|
25 |
|
26 | deep-eq = require 'deep-equal'
|
27 |
|
28 | # This module provides a minimal, fully conforming, implementation of
|
29 | # the Identity container. It serves both as an example, and as a way to
|
30 | # test if the equations in the laws actually do what they're supposed
|
31 | # to.
|
32 |
|
33 | export class StaticIdentity
|
34 | (a) ->
|
35 | @value = a
|
36 | @is-empty = false
|
37 |
|
38 | # Semigroup
|
39 | concat: (b) ->
|
40 | | @is-empty => b
|
41 | | b.is-empty => this
|
42 | | otherwise => new Identity (@value ++ b.value)
|
43 |
|
44 | # Monoid
|
45 | @empty = -> new Identity <<< { is-empty: true }
|
46 |
|
47 | # Functor
|
48 | map: (f) -> new Identity (f @value)
|
49 |
|
50 | # Applicative / Monad
|
51 | ap: (b) -> new Identity (@value b.value)
|
52 |
|
53 | @of = (a) -> new Identity a
|
54 |
|
55 | # Chain / Monad
|
56 | chain: (f) -> f @value
|
57 |
|
58 | # Eq
|
59 | is-equal: (a) ->
|
60 | | @is-empty => a.is-empty
|
61 | | otherwise => !a.is-empty and (@value `deep-eq` a.value)
|
62 |
|
63 |
|
64 | export class Identity extends StaticIdentity
|
65 | of: StaticIdentity.of
|
66 | empty: StaticIdentity.empty
|
67 |
|
68 | delete Identity.of
|
69 | delete Identity.empty
|