haskell 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/Gemfile +0 -2
- data/README.md +56 -22
- data/haskell.gemspec +2 -2
- data/lib/haskell.rb +11 -25
- data/lib/haskell/assert_arg_type.rb +14 -0
- data/lib/haskell/assert_rtn_type.rb +16 -0
- data/lib/haskell/base.rb +7 -0
- data/lib/haskell/version.rb +1 -1
- data/test/test_haskell.rb +10 -7
- metadata +13 -11
- data/a +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e555bd13822ba64ac40eefd7874334266b76527b
|
4
|
+
data.tar.gz: 1203cdd7568b53f6931a59a0d5fecf0b754dbc3f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aca2299d010c4264f693a13dce7ce27c213363824838ba80312fd21ee5fdee7fafff60779ddb6fb0349a8ca6a71c146b08b8fe5c898843588009e00bea0178e7
|
7
|
+
data.tar.gz: edcaa3d3fb1be593d1ce45b5baebe1329419232b114fada299b20c4dbe047039d0c25c956e0cb942fd203bbc2433d530e7661c1b269b6780bf6e0703c15845b7
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
# Ruby with Type.
|
2
2
|
|
3
|
-
|
3
|
+
Matz has mentioned Ruby3.0 with static type at some confluences. But almost all rubyists(include me) are not sure how typed Ruby is.
|
4
|
+
|
5
|
+
But it's worth thinking more. This gem is kind of trial without so much side-effect.
|
4
6
|
|
7
|
+
```rb
|
5
8
|
require 'haskell'
|
6
9
|
|
7
|
-
# Ruby 2.1.0+
|
10
|
+
# ex1: (Ruby 2.1.0+)
|
8
11
|
class MyClass
|
9
|
-
|
12
|
+
type Numeric >= Numeric >= Numeric, def sum(x, y)
|
10
13
|
x + y
|
11
14
|
end
|
12
15
|
|
13
16
|
type Numeric >= Numeric >= Numeric, def wrong_sum(x, y)
|
14
|
-
|
17
|
+
'string'
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
@@ -24,7 +27,22 @@ MyClass.new.sum(1, 'string')
|
|
24
27
|
MyClass.new.wrong_sum(1, 2)
|
25
28
|
#=> TypeError: Expected wrong_sum to return Numeric but got "str" instead
|
26
29
|
|
27
|
-
|
30
|
+
|
31
|
+
# ex2: (Ruby 2.1.0+)
|
32
|
+
class People
|
33
|
+
type People >= Any, def marry(people)
|
34
|
+
# Your Ruby code as usual
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
People.new.marry(People.new)
|
39
|
+
#=> no error
|
40
|
+
|
41
|
+
People.new.marry('non people')
|
42
|
+
#=> ArgumentError: Wrong type of argument, type of "non people" should be People
|
43
|
+
|
44
|
+
|
45
|
+
# ex3: (Ruby 1.8.0+)
|
28
46
|
class MyClass
|
29
47
|
def sum(x, y)
|
30
48
|
x + y
|
@@ -33,6 +51,38 @@ class MyClass
|
|
33
51
|
end
|
34
52
|
```
|
35
53
|
|
54
|
+
## Feature
|
55
|
+
### Typed method can coexist with non-typed method
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
# It's totally OK!!
|
59
|
+
class MyClass
|
60
|
+
type Numeric >= Numeric >= Numeric, def sum(x, y)
|
61
|
+
x + y
|
62
|
+
end
|
63
|
+
|
64
|
+
def wrong_sum(x, y)
|
65
|
+
'string'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
### Duck typing
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
|
74
|
+
class MyClass
|
75
|
+
type Any >= Numeric, def foo(any_obj)
|
76
|
+
1
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# It's totally OK!!
|
81
|
+
MyClass.new.foo(1)
|
82
|
+
# It's totally OK!!
|
83
|
+
MyClass.new.foo('str')
|
84
|
+
```
|
85
|
+
|
36
86
|
## Installation
|
37
87
|
|
38
88
|
Add this line to your application's Gemfile:
|
@@ -49,22 +99,6 @@ Or install it yourself as:
|
|
49
99
|
|
50
100
|
$ gem install haskell
|
51
101
|
|
52
|
-
## More example
|
53
|
-
```ruby
|
54
|
-
class People
|
55
|
-
type People >= Any, def marry(people)
|
56
|
-
# Your Ruby code as usual
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
People.new.marry(People.new)
|
61
|
-
#=> no error
|
62
|
-
|
63
|
-
People.new.marry('non people')
|
64
|
-
#=> ArgumentError: Wrong type of argument, type of "non people" should be People
|
65
|
-
|
66
|
-
```
|
67
|
-
|
68
102
|
## Contributing
|
69
103
|
|
70
104
|
1. Fork it ( https://github.com/[my-github-username]/haskell/fork )
|
@@ -75,4 +109,4 @@ People.new.marry('non people')
|
|
75
109
|
|
76
110
|
|
77
111
|
## Credits
|
78
|
-
[@chancancode](https://github.com/chancancode) first brought this to my attention.
|
112
|
+
[@chancancode](https://github.com/chancancode) first brought this to my attention. I've stolen some idea from him.
|
data/haskell.gemspec
CHANGED
@@ -19,8 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.add_development_dependency "bundler"
|
23
|
-
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "bundler"
|
23
|
+
spec.add_development_dependency "rake"
|
24
24
|
spec.add_development_dependency "rake-compiler"
|
25
25
|
spec.add_development_dependency "minitest"
|
26
26
|
end
|
data/lib/haskell.rb
CHANGED
@@ -1,27 +1,15 @@
|
|
1
1
|
require 'haskell/type_list'
|
2
|
+
require 'haskell/base'
|
3
|
+
require 'haskell/assert_arg_type'
|
4
|
+
require 'haskell/assert_rtn_type'
|
2
5
|
|
3
|
-
module Haskell
|
4
|
-
class << self
|
5
|
-
def assert_arg_type(meth, args, klasses)
|
6
|
+
module Haskell; end
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
def assert_rtn_type(meth, rtn, klass)
|
15
|
-
if wrong_type?(rtn, klass)
|
16
|
-
raise TypeError, "Expected #{meth} to return #{klass} but got #{rtn.inspect} instead"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def wrong_type?(obj, klass)
|
21
|
-
!(obj.is_a?(klass) || klass == Any)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
8
|
+
# New Class(Type)
|
9
|
+
class Any; end
|
10
|
+
module Boolean; end
|
11
|
+
TrueClass.send(:include, Boolean)
|
12
|
+
FalseClass.send(:include, Boolean)
|
25
13
|
|
26
14
|
class Module
|
27
15
|
private
|
@@ -32,13 +20,11 @@ class Module
|
|
32
20
|
|
33
21
|
def type(type_list, meth)
|
34
22
|
__haskell__.send(:define_method, meth) do |*args, &block|
|
35
|
-
::Haskell.
|
23
|
+
::Haskell::AssertArgType.execute(meth, args, type_list.args)
|
36
24
|
rtn = super(*args, &block)
|
37
|
-
::Haskell.
|
25
|
+
::Haskell::AssertRtnType.execute(meth, rtn, type_list.rtn)
|
38
26
|
rtn
|
39
27
|
end
|
40
28
|
self
|
41
29
|
end
|
42
30
|
end
|
43
|
-
|
44
|
-
class Any; end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Haskell
|
2
|
+
module AssertArgType
|
3
|
+
extend Base
|
4
|
+
|
5
|
+
def self.execute(meth, args, klasses)
|
6
|
+
args.each_with_index do |arg, i|
|
7
|
+
if wrong_type?(arg, klasses[i])
|
8
|
+
raise ArgumentError, "Wrong type of argument, type of #{arg.inspect} should be #{klasses[i]}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Haskell
|
2
|
+
module AssertRtnType
|
3
|
+
extend Base
|
4
|
+
|
5
|
+
def self.execute(meth, rtn, klass)
|
6
|
+
if wrong_type?(rtn, klass)
|
7
|
+
raise TypeError, "Expected #{meth} to return #{klass} but got #{rtn.inspect} instead"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.wrong_type?(obj, klass)
|
12
|
+
!(obj.is_a?(klass) || klass == Any)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
data/lib/haskell/base.rb
ADDED
data/lib/haskell/version.rb
CHANGED
data/test/test_haskell.rb
CHANGED
@@ -21,12 +21,14 @@ class TestHaskell < MiniTest::Unit::TestCase
|
|
21
21
|
assert_correct_type Numeric >= String, [@numeric], @string
|
22
22
|
assert_correct_type Numeric >= Hash, [@numeric], @hash
|
23
23
|
assert_correct_type Numeric >= Symbol, [@numeric], @symbol
|
24
|
-
|
25
|
-
assert_correct_type Numeric >=
|
26
|
-
|
27
|
-
assert_correct_type
|
28
|
-
assert_correct_type
|
29
|
-
assert_correct_type
|
24
|
+
assert_correct_type Numeric >= Boolean, [@numeric], true
|
25
|
+
assert_correct_type Numeric >= Boolean, [@numeric], false
|
26
|
+
|
27
|
+
assert_correct_type Boolean >= Numeric >= Numeric, [true, @numeric], @numeric
|
28
|
+
assert_correct_type Boolean >= Array >= Array, [true, @array ], @array
|
29
|
+
assert_correct_type Boolean >= String >= String, [true, @string ], @string
|
30
|
+
assert_correct_type Boolean >= Hash >= Hash, [true, @hash ], @hash
|
31
|
+
assert_correct_type Boolean >= Symbol >= Symbol, [true, @symbol ], @symbol
|
30
32
|
end
|
31
33
|
|
32
34
|
def test_wrong_return_type
|
@@ -84,9 +86,10 @@ class TestHaskell < MiniTest::Unit::TestCase
|
|
84
86
|
|
85
87
|
def define_test_method(type_list, args, val)
|
86
88
|
klass = Class.new.class_eval <<-RUBY_CODE
|
87
|
-
|
89
|
+
def call(#{arg_literal(args.count)})
|
88
90
|
#{obj_literal(val)}
|
89
91
|
end
|
92
|
+
type #{obj_literal(type_list)}, :call
|
90
93
|
RUBY_CODE
|
91
94
|
|
92
95
|
klass.new
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haskell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- gogotanaka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake-compiler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,13 +81,15 @@ files:
|
|
81
81
|
- LICENSE.txt
|
82
82
|
- README.md
|
83
83
|
- Rakefile
|
84
|
-
- a
|
85
84
|
- bin/haskell
|
86
85
|
- ext/haskell/extconf.rb
|
87
86
|
- ext/haskell/haskell.c
|
88
87
|
- ext/haskell/haskell.h
|
89
88
|
- haskell.gemspec
|
90
89
|
- lib/haskell.rb
|
90
|
+
- lib/haskell/assert_arg_type.rb
|
91
|
+
- lib/haskell/assert_rtn_type.rb
|
92
|
+
- lib/haskell/base.rb
|
91
93
|
- lib/haskell/type_list.rb
|
92
94
|
- lib/haskell/version.rb
|
93
95
|
- test/minitest_helper.rb
|
data/a
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
def test_any
|
2
|
-
assert_wrong_arg @symbo >= @symbo, [@array ], @numeric
|
3
|
-
assert_wrong_arg @symbo >= @symbo, [@string], @numeric
|
4
|
-
assert_wrong_arg @symbo >= @symbo, [@hash ], @numeric
|
5
|
-
assert_wrong_arg @symbo >= @symbo, [@symbol], @numeric
|
6
|
-
|
7
|
-
assert_wrong_arg @symbo >= @symbo >= @symbo, [@numeric, @array ], @numeric
|
8
|
-
assert_wrong_arg @symbo >= @symbo >= @symbo, [@numeric, @string], @numeric
|
9
|
-
assert_wrong_arg @symbo >= @symbo >= @symbo, [@numeric, @hash ], @numeric
|
10
|
-
assert_wrong_arg @symbo >= @symbo >= @symbo, [@numeric, @symbol], @numeric
|
11
|
-
en
|