kleisli 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -1
- data/lib/kleisli/applicative_functor.rb +4 -0
- data/lib/kleisli/either.rb +8 -0
- data/lib/kleisli/maybe.rb +18 -0
- data/lib/kleisli/version.rb +1 -1
- data/test/kleisli/either_test.rb +12 -0
- data/test/kleisli/maybe_test.rb +12 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 997aca6d77f858cf9262df7edbc913179cd8004f
|
4
|
+
data.tar.gz: dac24d37b400e98703e6299fb6a702ea5df773eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 009f9357a66c1003610f90cd86e734c00632efa6b8b511d5eec2bdc91daceb41bc3f1ebf667615065aefd506435510f8de97a83518a2e6259241f649224d0fef
|
7
|
+
data.tar.gz: 77f136e1fb92e6d315c7b423aa2c5e8f32b3f3f1f2ec0071488c51557cab9d52d51a3d6b1f105211f2525979825456a4ea09ea53aa78d6e0b2809ffa581f9ec7
|
data/README.md
CHANGED
@@ -23,7 +23,10 @@ which for each monad below).
|
|
23
23
|
Kleisli uses a clever Ruby syntax trick to implement the `bind` operator, which
|
24
24
|
looks like this: `>->` when used with a block. We will probably burn in hell
|
25
25
|
for this. You can also use `>` or `>>` if you're going to pass in a proc or
|
26
|
-
|
26
|
+
lambda object.
|
27
|
+
|
28
|
+
`Maybe` and `Either` are applicative functors with the apply operator `*`. Read
|
29
|
+
further to see how it works.
|
27
30
|
|
28
31
|
### Function composition
|
29
32
|
|
@@ -121,6 +124,18 @@ Maybe(user).fmap(&:address).fmap(&:street)
|
|
121
124
|
# => None()
|
122
125
|
```
|
123
126
|
|
127
|
+
### `*` (applicative functor's apply)
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
require "kleisli"
|
131
|
+
|
132
|
+
add = -> x, y { x + y }
|
133
|
+
Some(add) * Some(10) * Some(2)
|
134
|
+
# => Some(12)
|
135
|
+
Some(add) * None() * Some(2)
|
136
|
+
# => None
|
137
|
+
```
|
138
|
+
|
124
139
|
## Try
|
125
140
|
|
126
141
|
The Try monad is useful to express a pipeline of computations that might throw
|
@@ -239,6 +254,18 @@ result # => Right(20)
|
|
239
254
|
result # => Left("wrong")
|
240
255
|
```
|
241
256
|
|
257
|
+
### `*` (applicative functor's apply)
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
require "kleisli"
|
261
|
+
|
262
|
+
add = -> x, y { x + y }
|
263
|
+
Right(add) * Right(10) * Right(2)
|
264
|
+
# => Some(12)
|
265
|
+
Right(add) * Left("error") * Right(2)
|
266
|
+
# => Left("error")
|
267
|
+
```
|
268
|
+
|
242
269
|
### `or`
|
243
270
|
|
244
271
|
`or` does pretty much what would you expect:
|
data/lib/kleisli/either.rb
CHANGED
data/lib/kleisli/maybe.rb
CHANGED
@@ -16,6 +16,14 @@ module Kleisli
|
|
16
16
|
value == other.value
|
17
17
|
end
|
18
18
|
|
19
|
+
def *(other)
|
20
|
+
self >-> f {
|
21
|
+
other >-> val {
|
22
|
+
Maybe.lift(f.arity > 1 ? f.curry.call(val) : f.call(val))
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
19
27
|
class None < Maybe
|
20
28
|
def fmap(&f)
|
21
29
|
self
|
@@ -28,6 +36,11 @@ module Kleisli
|
|
28
36
|
def or(other)
|
29
37
|
other
|
30
38
|
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
"None"
|
42
|
+
end
|
43
|
+
alias inspect to_s
|
31
44
|
end
|
32
45
|
|
33
46
|
class Some < Maybe
|
@@ -46,6 +59,11 @@ module Kleisli
|
|
46
59
|
def or(other)
|
47
60
|
self
|
48
61
|
end
|
62
|
+
|
63
|
+
def to_s
|
64
|
+
"Some(#{@value})"
|
65
|
+
end
|
66
|
+
alias inspect to_s
|
49
67
|
end
|
50
68
|
end
|
51
69
|
end
|
data/lib/kleisli/version.rb
CHANGED
data/test/kleisli/either_test.rb
CHANGED
@@ -46,4 +46,16 @@ class EitherTest < MiniTest::Unit::TestCase
|
|
46
46
|
def test_pointfree
|
47
47
|
assert_equal Right(10), Right(5) >> F . fn(&Right) . *(2)
|
48
48
|
end
|
49
|
+
|
50
|
+
def test_applicative_functor_right_arity_1
|
51
|
+
assert_equal Right(20), Right(-> x { x * 2 }) * Right(10)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_applicative_functor_right_arity_2
|
55
|
+
assert_equal Right(20), Right(-> x, y { x * y }) * Right(10) * Right(2)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_applicative_functor_left
|
59
|
+
assert_equal Left("error"), Right(-> x, y { x * y }) * Left("error") * Right(2)
|
60
|
+
end
|
49
61
|
end
|
data/test/kleisli/maybe_test.rb
CHANGED
@@ -24,4 +24,16 @@ class MaybeTest < MiniTest::Unit::TestCase
|
|
24
24
|
def test_fmap_some
|
25
25
|
assert_equal Some(6), Some(3).fmap { |x| x * 2 }
|
26
26
|
end
|
27
|
+
|
28
|
+
def test_applicative_functor_some_arity_1
|
29
|
+
assert_equal Some(20), Maybe(-> x { x * 2 }) * Maybe(10)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_applicative_functor_some_arity_2
|
33
|
+
assert_equal Some(20), Maybe(-> x, y { x * y }) * Maybe(10) * Maybe(2)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_applicative_functor_none
|
37
|
+
assert_equal None(), Maybe(-> x, y { x * y }) * None() * Maybe(2)
|
38
|
+
end
|
27
39
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kleisli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josep M. Bach
|
@@ -55,6 +55,7 @@ files:
|
|
55
55
|
- Rakefile
|
56
56
|
- kleisli.gemspec
|
57
57
|
- lib/kleisli.rb
|
58
|
+
- lib/kleisli/applicative_functor.rb
|
58
59
|
- lib/kleisli/blank.rb
|
59
60
|
- lib/kleisli/composition.rb
|
60
61
|
- lib/kleisli/either.rb
|