funkr 0.0.24 → 0.0.30

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7cb4f5366a7c1c68082cb5982e5cd7700440d94344fdfb8cdff7bd94b723bb4a
4
+ data.tar.gz: 4c79978d034dbbc0fc650644808ca3de77efa6e934770a4602d09ea042891c01
5
+ SHA512:
6
+ metadata.gz: e2767fe18dbf634574240a8b40acf5a8d42f2caa0770605a3b9b5e25ff62b9307552088da7a381f9c3a5e5ee3cb2b9dd2a6db93f7d8034b7ad6641d595cc5307
7
+ data.tar.gz: c7110ff660fb041f5f09b63bff32e187c99fccfec855d75d1be99993115f1654255144185140cdd1b47dffc4c78d3a8d2fac0e4d60fe9ab2ab120ef05726c6ed
data/README CHANGED
@@ -1,13 +1,16 @@
1
1
  Funkr brings some common functional programming constructs to ruby.
2
2
 
3
- In particular, it offers a simple mechanism to create Algebraïc Data
4
- Types and do pattern matching on them. For an exemple
5
- implementation, {Funkr::Types see provided classes}.
3
+ In particular, it offers a simple mechanism to create Algebraic Data
4
+ Types and do pattern matching on them. For an exemple implementation,
5
+ see provided classes.
6
6
 
7
7
  It also provide modules for common categories (Monoid, Monad,
8
8
  Functor, Applicative ...), and extends common types to support
9
9
  categories they belongs to (Array, Hash ...). Categories can also be
10
- used with custom types, {Funkr::Types see provided classes}.
10
+ used with custom types, see provided classes.
11
11
 
12
12
  To get started, we recommand you to read the tests, and get feets wet
13
- with provided Algebraic Data Types (like Maybe).
13
+ with provided Algebraic Data Types (like Maybe).
14
+
15
+ Funkr is heavily used by its authors in production at
16
+ http://www.atikteam.com/en to ensure better code reliability.
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  $:.push File.expand_path("../lib", __FILE__)
3
2
  require "funkr/version"
4
3
 
@@ -9,8 +8,27 @@ Gem::Specification.new do |s|
9
8
  s.authors = ["Paul Rivier"]
10
9
  s.email = ["paul (dot) r (dot) ml (at) gmail (dot) com"]
11
10
  s.homepage = "http://github.com/paul-r-ml/funkr"
12
- s.summary = %q{[EXPERIMENTAL] Some functionnal constructs for ruby}
13
- s.description = %q{[EXPERIMENTAL] Some functionnal constructs for ruby, like ADT, functors, monads}
11
+ s.summary = %q{Functionnal toolbox for Ruby}
12
+ s.description = <<EOF
13
+ Funkr is a functionnal toolbox for the Ruby language.
14
+
15
+ In particular, it offers a simple mechanism to create Algebraic Data
16
+ Types and do pattern matching on them.
17
+
18
+ -
19
+
20
+ It also provide modules for common categories (Monoid, Monad,
21
+ Functor, Applicative ...), and extends common types to support
22
+ categories they belongs to (Array, Hash ...). Categories can also be
23
+ used with custom types, see provided classes.
24
+
25
+ -
26
+
27
+ Array and Hash classes are extended with methods providing correct
28
+ behaviour with respect to categories. Enumerable module comes with
29
+ a lot of useful functions for working with lists and sets. See the
30
+ module documentation and the test suite for examples.
31
+ EOF
14
32
 
15
33
  s.rubyforge_project = "funkr"
16
34
 
@@ -18,5 +36,5 @@ Gem::Specification.new do |s|
18
36
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
37
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
38
  s.require_paths = ["lib"]
21
- s.add_development_dependency 'rake', '~> 0.9.2'
39
+ s.add_development_dependency 'rake', '~> 12.3'
22
40
  end
@@ -13,7 +13,7 @@ module Funkr
13
13
  end
14
14
 
15
15
  # Declare ADT constructors, for example :
16
- # class Maybe < ADT; adt :just, :nothing; end
16
+ # class Maybe < ADT; adt :just, :nothing; end
17
17
  def self.adt(*constructs)
18
18
  build_adt(constructs)
19
19
  build_matcher(constructs)
@@ -22,11 +22,11 @@ module Funkr
22
22
  def self.matcher; @matcher; end
23
23
 
24
24
  # Match your ADT against its constructors, for example :
25
- # a = Maybe.just("hello")
26
- # a.match do |on|
27
- # on.just{|x| puts x}
28
- # on.nothing{ }
29
- # end
25
+ # a = Maybe.just("hello")
26
+ # a.match do |on|
27
+ # on.just{|x| puts x}
28
+ # on.nothing{ }
29
+ # end
30
30
  def match(&block)
31
31
  self.class.matcher.match_with(normal_form, &block)
32
32
  end
@@ -14,7 +14,7 @@ module Funkr
14
14
  def self.build_matchers(constructs)
15
15
  @constructs = constructs
16
16
  constructs.each do |c|
17
- name, *data = c
17
+ name, *_ = c
18
18
  define_method(name) do |&b|
19
19
  @undefined.delete(name)
20
20
  if @const == name then
@@ -1,4 +1,4 @@
1
- require 'funkr/extensions/fixnum'
1
+ require 'funkr/extensions/integer'
2
2
  require 'funkr/extensions/array'
3
3
  require 'funkr/extensions/enumerable'
4
4
  require 'funkr/extensions/hash'
@@ -17,9 +17,10 @@ class Array
17
17
 
18
18
 
19
19
  # Array can be made an applicative functor, for example :
20
- # f = Array.curry_lift_proc{|x,y| x + y}
21
- # f.apply([0,4]).apply([5,7]) => [5, 7, 9, 11]
22
- # f.apply([0,4]).apply([]) => []
20
+ #
21
+ # f = Array.curry_lift_proc{|x,y| x + y}
22
+ # f.apply([0,4]).apply([5,7]) => [5, 7, 9, 11]
23
+ # f.apply([0,4]).apply([]) => []
23
24
  include Applicative
24
25
  extend Applicative::ClassMethods
25
26
 
@@ -49,10 +50,12 @@ class Array
49
50
  end
50
51
 
51
52
 
52
- # Array is also a monad
53
53
  include Monad
54
54
  extend Monad::ClassMethods
55
55
 
56
+ # Array is also a monad
57
+ #
58
+ # [1,2].bind{|x| [3,4].bind{|y| x + y}} # => [4,5,5,6]
56
59
  def bind(&block)
57
60
  self.map(&block).flatten(1)
58
61
  end
@@ -40,26 +40,27 @@ module Enumerable
40
40
  return [ inc, [] ]
41
41
  end
42
42
 
43
- # Constitue des groupes disjoints de n éléments au plus
43
+ # builds up disjoint groups of n elements or less
44
44
  def groups_of(n)
45
45
  g = self.take(n)
46
46
  return [] if g.empty?
47
47
  [g] + self.drop(n).groups_of(n)
48
48
  end
49
49
 
50
- # constitue des groupes de n éléments exactement, décalés de 1
50
+ # builds up sliding groups of exactly n elements
51
51
  def sliding_groups_of(n)
52
52
  return [] if self.size < n
53
53
  [ self.take(n) ] + self.drop(1).sliding_groups_of(n)
54
54
  end
55
55
 
56
- # trouve l'index d'une séquence
56
+ # find the position of a sequence
57
+ # [1,2,3,4,5,4,3,2,1].seq_index([4,3]) # => 5
57
58
  def seq_index(seq)
58
59
  self.sliding_groups_of(seq.size).index(seq)
59
60
  end
60
61
 
61
- # Prend un prédicat p(x,y), et construit un tableau dans lequel tous
62
- # les couples (a,b), tels que 'a' précède 'b', vérifient p(a,b).
62
+ # Takes a block predicate p(x,y) and builds an array of elements so
63
+ # that for any (a,b), a being before b in the list, p(a,b) holds.
63
64
  def make_uniq_by(&block)
64
65
  result = []
65
66
  self.each do |e|
@@ -68,8 +69,7 @@ module Enumerable
68
69
  return result
69
70
  end
70
71
 
71
- # difference entre 2 tableaux, retourne le triplet [ [missing] , [intersection], [added] ]
72
- # codé en impératif parce que inject est trop lent :(
72
+ # compare 2 enumerables, and returns [ [missing] , [intersection], [added] ]
73
73
  def diff_with(other, &block)
74
74
  m, i, a = [], [], []
75
75
  u_s = self.make_uniq_by(&block)
@@ -1,6 +1,6 @@
1
1
  require "funkr/categories/monoid"
2
2
 
3
- class Fixnum
3
+ class Integer
4
4
 
5
5
  include Funkr::Categories
6
6
 
@@ -10,6 +10,9 @@ class Fixnum
10
10
  def mplus(y)
11
11
  self + y
12
12
  end
13
+
14
+ def self.mzero
15
+ 0
16
+ end
13
17
 
14
18
  end
15
-
@@ -23,18 +23,18 @@ module Funkr
23
23
  ### Categories
24
24
 
25
25
  include Functor
26
-
27
- # Maybe.nothing.map{|x| something(x)} # => nothing
28
- # Maybe.just(x).map{|x| something(x)} # => just something(x)
29
- #
26
+
30
27
  # {Funkr::Categories::Functor#map see functor map}
28
+ #
29
+ # Maybe.nothing.map{|x| something(x)} # => nothing
30
+ # Maybe.just(x).map{|x| something(x)} # => just something(x)
31
31
  def map(&block)
32
32
  # This implementation isn't safe but is a bit faster than the
33
33
  # safe one. A safe implementation would be as follow :
34
- # self.match do |on|
35
- # on.just {|v| self.class.just(yield(v))}
36
- # on.nothing { self }
37
- # end
34
+ # self.match do |on|
35
+ # on.just {|v| self.class.just(yield(v))}
36
+ # on.nothing { self }
37
+ # end
38
38
  if self.just? then self.class.just(yield(unsafe_content))
39
39
  else self end
40
40
  end
@@ -42,27 +42,27 @@ module Funkr
42
42
  include Applicative
43
43
  extend Applicative::ClassMethods
44
44
 
45
- # Maybe can be made an applicative functor, for example :
46
- # f = Maybe.curry_lift_proc{|x,y| x + y}
47
- # a = Maybe.just(3)
48
- # b = Maybe.just(4)
49
- # c = Maybe.nothing
50
- # f.apply(a).apply(b) => Just 7
51
- # f.apply(a).apply(c) => Nothing
52
- #
53
45
  # {Funkr::Categories::Applicative#apply see applicative apply}
46
+ #
47
+ # Maybe can be made an applicative functor, for example :
48
+ # f = Maybe.curry_lift_proc{|x,y| x + y}
49
+ # a = Maybe.just(3)
50
+ # b = Maybe.just(4)
51
+ # c = Maybe.nothing
52
+ # f.apply(a).apply(b) => Just 7
53
+ # f.apply(a).apply(c) => Nothing
54
54
  def apply(to)
55
55
  # This implementation isn't safe but is a bit faster than the
56
56
  # safe one. A safe implementation would be as follow :
57
- # self.match do |f_on|
58
- # f_on.just do |f|
59
- # to.match do |t_on|
60
- # t_on.just {|t| self.class.unit(f.call(t)) }
61
- # t_on.nothing { to }
57
+ # self.match do |f_on|
58
+ # f_on.just do |f|
59
+ # to.match do |t_on|
60
+ # t_on.just {|t| self.class.unit(f.call(t)) }
61
+ # t_on.nothing { to }
62
+ # end
62
63
  # end
64
+ # f_on.nothing { self }
63
65
  # end
64
- # f_on.nothing { self }
65
- # end
66
66
  if self.just? and to.just? then
67
67
  self.class.unit(self.unsafe_content.call(to.unsafe_content))
68
68
  else self.class.nothing end
@@ -103,10 +103,10 @@ module Funkr
103
103
  def bind(&block)
104
104
  # This implementation isn't safe but is a bit faster than the
105
105
  # safe one. A safe implementation would be as follow :
106
- # self.match do |on|
107
- # on.just {|v| yield(v)}
108
- # on.nothing {self}
109
- # end
106
+ # self.match do |on|
107
+ # on.just {|v| yield(v)}
108
+ # on.nothing {self}
109
+ # end
110
110
  if self.just? then yield(self.unsafe_content)
111
111
  else self end
112
112
  end
@@ -11,16 +11,17 @@ module Funkr
11
11
  # mistyping it or by combining it with a different structure
12
12
  # - you have easy access to fields : named AND positional
13
13
  #
14
- # usage : r = SimpleRecord.new(Hash), then r.field
15
- # r = SimpleRecord.new( name: "Paul", age: 27 )
16
- # r.name # => "Paul"
17
- # r.age # => 27
18
- # name, age = r # => [ "Paul", 27 ]
19
- # r.with(age: 29) # => [ "Paul", 29 ]
14
+ # usage :
15
+ #
16
+ # r = SimpleRecord.new( name: "Paul", age: 27 )
17
+ # r.name # => "Paul"
18
+ # r.age # => 27
19
+ # name, age = r # => [ "Paul", 27 ]
20
+ # r.with(age: 29) # => [ "Paul", 29 ]
20
21
  #
21
22
  # other usage :
22
- # class Person < SimpleRecord; fields :name, :age; end
23
- # Person.new( name: Paul ) => Error, missing :age
23
+ # class Person < SimpleRecord; fields :name, :age; end
24
+ # Person.new( name: Paul ) => Error, missing :age
24
25
  class SimpleRecord < Array
25
26
 
26
27
  class << self; attr_accessor :fields_list; end
@@ -1,3 +1,3 @@
1
1
  module Funkr
2
- VERSION = "0.0.24"
2
+ VERSION = "0.0.30"
3
3
  end
@@ -66,4 +66,9 @@ class TestExtensions < Test::Unit::TestCase
66
66
  a.make_uniq_by{|x,y| x[:v] == y[:v]})
67
67
  end
68
68
 
69
+
70
+ def test_mconcat_integer
71
+ assert_equal(6, Integer.mconcat([1,2,3]))
72
+ end
73
+
69
74
  end
metadata CHANGED
@@ -1,49 +1,56 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: funkr
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 24
9
- version: 0.0.24
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.30
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - Paul Rivier
13
8
  autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2011-12-06 00:00:00 +01:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2020-11-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: rake
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
- requirements:
26
- - - ~>
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- - 9
31
- - 2
32
- version: 0.9.2
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '12.3'
33
20
  type: :development
34
- version_requirements: *id001
35
- description: "[EXPERIMENTAL] Some functionnal constructs for ruby, like ADT, functors, monads"
36
- email:
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '12.3'
27
+ description: |
28
+ Funkr is a functionnal toolbox for the Ruby language.
29
+
30
+ In particular, it offers a simple mechanism to create Algebraic Data
31
+ Types and do pattern matching on them.
32
+
33
+ -
34
+
35
+ It also provide modules for common categories (Monoid, Monad,
36
+ Functor, Applicative ...), and extends common types to support
37
+ categories they belongs to (Array, Hash ...). Categories can also be
38
+ used with custom types, see provided classes.
39
+
40
+ -
41
+
42
+ Array and Hash classes are extended with methods providing correct
43
+ behaviour with respect to categories. Enumerable module comes with
44
+ a lot of useful functions for working with lists and sets. See the
45
+ module documentation and the test suite for examples.
46
+ email:
37
47
  - paul (dot) r (dot) ml (at) gmail (dot) com
38
48
  executables: []
39
-
40
49
  extensions: []
41
-
42
50
  extra_rdoc_files: []
43
-
44
- files:
45
- - .gitignore
46
- - .travis.yml
51
+ files:
52
+ - ".gitignore"
53
+ - ".travis.yml"
47
54
  - Gemfile
48
55
  - README
49
56
  - Rakefile
@@ -61,8 +68,8 @@ files:
61
68
  - lib/funkr/extensions.rb
62
69
  - lib/funkr/extensions/array.rb
63
70
  - lib/funkr/extensions/enumerable.rb
64
- - lib/funkr/extensions/fixnum.rb
65
71
  - lib/funkr/extensions/hash.rb
72
+ - lib/funkr/extensions/integer.rb
66
73
  - lib/funkr/types.rb
67
74
  - lib/funkr/types/container.rb
68
75
  - lib/funkr/types/failable.rb
@@ -74,37 +81,27 @@ files:
74
81
  - test/test_hash.rb
75
82
  - test/test_maybe.rb
76
83
  - test/test_simple_records.rb
77
- has_rdoc: true
78
84
  homepage: http://github.com/paul-r-ml/funkr
79
85
  licenses: []
80
-
86
+ metadata: {}
81
87
  post_install_message:
82
88
  rdoc_options: []
83
-
84
- require_paths:
89
+ require_paths:
85
90
  - lib
86
- required_ruby_version: !ruby/object:Gem::Requirement
87
- none: false
88
- requirements:
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
89
93
  - - ">="
90
- - !ruby/object:Gem::Version
91
- segments:
92
- - 0
93
- version: "0"
94
- required_rubygems_version: !ruby/object:Gem::Requirement
95
- none: false
96
- requirements:
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
97
98
  - - ">="
98
- - !ruby/object:Gem::Version
99
- segments:
100
- - 0
101
- version: "0"
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
102
101
  requirements: []
103
-
104
102
  rubyforge_project: funkr
105
- rubygems_version: 1.3.7
103
+ rubygems_version: 2.7.6.2
106
104
  signing_key:
107
- specification_version: 3
108
- summary: "[EXPERIMENTAL] Some functionnal constructs for ruby"
105
+ specification_version: 4
106
+ summary: Functionnal toolbox for Ruby
109
107
  test_files: []
110
-