haskell 0.0.3 → 0.1.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 +20 -10
- data/lib/haskell/type_pair.rb +7 -0
- data/lib/haskell/version.rb +1 -1
- data/lib/haskell.rb +36 -17
- data/test/test_haskell.rb +53 -45
- metadata +2 -5
- data/lib/haskell/assert_arg_type.rb +0 -14
- data/lib/haskell/assert_rtn_type.rb +0 -16
- data/lib/haskell/base.rb +0 -7
- data/lib/haskell/type_list.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4091853a74cb3916531770c015d74a1846249825
|
4
|
+
data.tar.gz: abacdf2cda587ffc59f0103163ce1bda1e235f79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8688fce196d3cff82e187f6cc5979386016855cc0658aed2617861e6be3e45ea0a1cfcf1f9f32c2cd0bd6957be817efd306817b363e4826c885f2d62c8b4125e
|
7
|
+
data.tar.gz: 86ee71cc6c0ccdf30763bdb58a466e0384b977468ab44532c496dbdcb8a5b783587b8d5264f3520b835962c99d7d39b85e587c5f51ded646e3a62181825e789c
|
data/README.md
CHANGED
@@ -9,11 +9,11 @@ require 'haskell'
|
|
9
9
|
|
10
10
|
# ex1: (Ruby 2.1.0+)
|
11
11
|
class MyClass
|
12
|
-
type Numeric
|
12
|
+
type Numeric, Numeric >= Numeric, def sum(x, y)
|
13
13
|
x + y
|
14
14
|
end
|
15
15
|
|
16
|
-
type Numeric
|
16
|
+
type Numeric, Numeric >= Numeric, def wrong_sum(x, y)
|
17
17
|
'string'
|
18
18
|
end
|
19
19
|
end
|
@@ -47,7 +47,7 @@ class MyClass
|
|
47
47
|
def sum(x, y)
|
48
48
|
x + y
|
49
49
|
end
|
50
|
-
type Numeric
|
50
|
+
type Numeric, Numeric >= Numeric, :sum
|
51
51
|
end
|
52
52
|
```
|
53
53
|
|
@@ -57,7 +57,7 @@ end
|
|
57
57
|
```ruby
|
58
58
|
# It's totally OK!!
|
59
59
|
class MyClass
|
60
|
-
type Numeric
|
60
|
+
type Numeric, Numeric >= Numeric, def sum(x, y)
|
61
61
|
x + y
|
62
62
|
end
|
63
63
|
|
@@ -99,14 +99,24 @@ Or install it yourself as:
|
|
99
99
|
|
100
100
|
$ gem install haskell
|
101
101
|
|
102
|
-
## Contributing
|
103
102
|
|
104
|
-
|
105
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
106
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
107
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
108
|
-
5. Create a new Pull Request
|
103
|
+
### Contributing
|
109
104
|
|
105
|
+
Fork it ( https://github.com/[my-github-username]/haskell/fork )
|
106
|
+
|
107
|
+
Create your feature branch (`git checkout -b my-new-feature`)
|
108
|
+
|
109
|
+
$ bundle install --path vendor/bundle
|
110
|
+
|
111
|
+
Commit your changes (`git commit -am 'Add some feature'`)
|
112
|
+
|
113
|
+
$ bundle exec rake test
|
114
|
+
|
115
|
+
> 5 runs, 39 assertions, 0 failures, 0 errors, 0 skips
|
116
|
+
|
117
|
+
Push to the branch (`git push origin my-new-feature`)
|
118
|
+
|
119
|
+
Create a new Pull Request
|
110
120
|
|
111
121
|
## Credits
|
112
122
|
[@chancancode](https://github.com/chancancode) first brought this to my attention. I've stolen some idea from him.
|
data/lib/haskell/version.rb
CHANGED
data/lib/haskell.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
|
-
require 'haskell/
|
2
|
-
require 'haskell/base'
|
3
|
-
require 'haskell/assert_arg_type'
|
4
|
-
require 'haskell/assert_rtn_type'
|
1
|
+
require 'haskell/type_pair'
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
# New Class(Type)
|
3
|
+
# Builtin Contracts
|
9
4
|
class Any; end
|
10
5
|
module Boolean; end
|
11
6
|
TrueClass.send(:include, Boolean)
|
@@ -13,18 +8,42 @@ FalseClass.send(:include, Boolean)
|
|
13
8
|
|
14
9
|
class Module
|
15
10
|
private
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
def __haskell__
|
12
|
+
prepend (@__haskell__ = Module.new) unless @__haskell__
|
13
|
+
@__haskell__
|
14
|
+
end
|
15
|
+
|
16
|
+
def type(*arguments)
|
17
|
+
*arg_types, type_pair, meth = arguments
|
18
|
+
|
19
|
+
__haskell__.send(:define_method, meth) do |*args, &block|
|
20
|
+
::Haskell.assert_arg_type(meth, args, arg_types << type_pair.last_arg_type)
|
21
|
+
rtn = super(*args, &block)
|
22
|
+
::Haskell.assert_trn_type(meth, rtn, type_pair.rtn_type)
|
23
|
+
rtn
|
19
24
|
end
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
20
28
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
29
|
+
module Haskell
|
30
|
+
class << self
|
31
|
+
def assert_arg_type(meth, args, klasses)
|
32
|
+
args.each_with_index do |arg, i|
|
33
|
+
if wrong_type?(arg, klasses[i])
|
34
|
+
raise ArgumentError, "Wrong type of argument, type of #{arg.inspect} should be #{klasses[i]}"
|
35
|
+
end
|
27
36
|
end
|
28
|
-
self
|
29
37
|
end
|
38
|
+
|
39
|
+
def assert_trn_type(meth, rtn, klass)
|
40
|
+
if wrong_type?(rtn, klass)
|
41
|
+
raise TypeError, "Expected #{meth} to return #{klass} but got #{rtn.inspect} instead"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def wrong_type?(obj, klass)
|
46
|
+
!(obj.is_a?(klass) || klass == Any)
|
47
|
+
end
|
48
|
+
end
|
30
49
|
end
|
data/test/test_haskell.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
require 'minitest_helper'
|
2
|
-
|
2
|
+
class TypePair
|
3
|
+
def to_s
|
4
|
+
"#{last_arg_type} >= #{rtn_type}"
|
5
|
+
end
|
6
|
+
end
|
3
7
|
class TestHaskell < MiniTest::Unit::TestCase
|
4
8
|
def setup
|
5
9
|
@string = 'str'
|
@@ -10,61 +14,65 @@ class TestHaskell < MiniTest::Unit::TestCase
|
|
10
14
|
end
|
11
15
|
|
12
16
|
def test_type_list
|
13
|
-
assert_equal_to_s "Numeric
|
14
|
-
assert_equal_to_s "Numeric
|
15
|
-
assert_equal_to_s "
|
17
|
+
assert_equal_to_s "Numeric >= Numeric", Numeric >= Numeric
|
18
|
+
assert_equal_to_s "Numeric >= Array", Numeric >= Array
|
19
|
+
assert_equal_to_s "Array >= String", Array >= String
|
16
20
|
end
|
17
21
|
|
18
22
|
def test_correct_type
|
19
|
-
assert_correct_type Numeric >= Numeric, [@numeric], @numeric
|
20
|
-
assert_correct_type Numeric >= Array,
|
21
|
-
assert_correct_type Numeric >= String,
|
22
|
-
assert_correct_type Numeric >= Hash,
|
23
|
-
assert_correct_type Numeric >= Symbol,
|
24
|
-
assert_correct_type Numeric >= Boolean, [@numeric], true
|
25
|
-
assert_correct_type Numeric >= Boolean, [@numeric], false
|
26
|
-
|
27
|
-
assert_correct_type Boolean
|
28
|
-
assert_correct_type Boolean
|
29
|
-
assert_correct_type Boolean
|
30
|
-
assert_correct_type Boolean
|
31
|
-
assert_correct_type Boolean
|
23
|
+
assert_correct_type [Numeric >= Numeric], [@numeric], @numeric
|
24
|
+
assert_correct_type [Numeric >= Array ], [@numeric], @array
|
25
|
+
assert_correct_type [Numeric >= String ], [@numeric], @string
|
26
|
+
assert_correct_type [Numeric >= Hash ], [@numeric], @hash
|
27
|
+
assert_correct_type [Numeric >= Symbol ], [@numeric], @symbol
|
28
|
+
assert_correct_type [Numeric >= Boolean], [@numeric], true
|
29
|
+
assert_correct_type [Numeric >= Boolean], [@numeric], false
|
30
|
+
|
31
|
+
assert_correct_type [Boolean, Numeric >= Numeric], [true, @numeric], @numeric
|
32
|
+
assert_correct_type [Boolean, Array >= Array ], [true, @array ], @array
|
33
|
+
assert_correct_type [Boolean, String >= String ], [true, @string ], @string
|
34
|
+
assert_correct_type [Boolean, Hash >= Hash ], [true, @hash ], @hash
|
35
|
+
assert_correct_type [Boolean, Symbol >= Symbol ], [true, @symbol ], @symbol
|
32
36
|
end
|
33
37
|
|
34
38
|
def test_wrong_return_type
|
35
|
-
assert_wrong_rtn Numeric >= Numeric, [@numeric], @array
|
36
|
-
assert_wrong_rtn Numeric >= Numeric, [@numeric], @string
|
37
|
-
assert_wrong_rtn Numeric >= Numeric, [@numeric], @hash
|
38
|
-
assert_wrong_rtn Numeric >= Numeric, [@numeric], @symbol
|
39
|
-
|
40
|
-
|
41
|
-
assert_wrong_rtn Numeric
|
42
|
-
assert_wrong_rtn Numeric
|
43
|
-
assert_wrong_rtn Numeric
|
39
|
+
assert_wrong_rtn [Numeric >= Numeric], [@numeric], @array
|
40
|
+
assert_wrong_rtn [Numeric >= Numeric], [@numeric], @string
|
41
|
+
assert_wrong_rtn [Numeric >= Numeric], [@numeric], @hash
|
42
|
+
assert_wrong_rtn [Numeric >= Numeric], [@numeric], @symbol
|
43
|
+
assert_wrong_rtn [Numeric >= Numeric], [@numeric], true
|
44
|
+
|
45
|
+
assert_wrong_rtn [Numeric, Numeric >= Numeric], [@numeric, @numeric], @array
|
46
|
+
assert_wrong_rtn [Numeric, Numeric >= Numeric], [@numeric, @numeric], @string
|
47
|
+
assert_wrong_rtn [Numeric, Numeric >= Numeric], [@numeric, @numeric], @hash
|
48
|
+
assert_wrong_rtn [Numeric, Numeric >= Numeric], [@numeric, @numeric], @symbol
|
49
|
+
assert_wrong_rtn [Numeric, Numeric >= Numeric], [@numeric, @numeric], true
|
44
50
|
end
|
45
51
|
|
46
52
|
def test_wrong_args_type
|
47
|
-
assert_wrong_arg Numeric >= Numeric, [@array ], @numeric
|
48
|
-
assert_wrong_arg Numeric >= Numeric, [@string], @numeric
|
49
|
-
assert_wrong_arg Numeric >= Numeric, [@hash ], @numeric
|
50
|
-
assert_wrong_arg Numeric >= Numeric, [@symbol], @numeric
|
51
|
-
|
52
|
-
|
53
|
-
assert_wrong_arg Numeric
|
54
|
-
assert_wrong_arg Numeric
|
55
|
-
assert_wrong_arg Numeric
|
53
|
+
assert_wrong_arg [Numeric >= Numeric], [@array ], @numeric
|
54
|
+
assert_wrong_arg [Numeric >= Numeric], [@string], @numeric
|
55
|
+
assert_wrong_arg [Numeric >= Numeric], [@hash ], @numeric
|
56
|
+
assert_wrong_arg [Numeric >= Numeric], [@symbol], @numeric
|
57
|
+
assert_wrong_arg [Numeric >= Numeric], [true ], @numeric
|
58
|
+
|
59
|
+
assert_wrong_arg [Numeric, Numeric >= Numeric], [@numeric, @array ], @numeric
|
60
|
+
assert_wrong_arg [Numeric, Numeric >= Numeric], [@numeric, @string], @numeric
|
61
|
+
assert_wrong_arg [Numeric, Numeric >= Numeric], [@numeric, @hash ], @numeric
|
62
|
+
assert_wrong_arg [Numeric, Numeric >= Numeric], [@numeric, @symbol], @numeric
|
63
|
+
assert_wrong_arg [Numeric, Numeric >= Numeric], [@numeric, true ], @numeric
|
56
64
|
end
|
57
65
|
|
58
66
|
def test_any
|
59
|
-
assert_correct_type Any >= Any, [@array ], @numeric
|
60
|
-
assert_correct_type Any >= Any, [@string], @numeric
|
61
|
-
assert_correct_type Any >= Any, [@hash ], @numeric
|
62
|
-
assert_correct_type Any >= Any, [@symbol], @numeric
|
63
|
-
|
64
|
-
assert_correct_type Any
|
65
|
-
assert_correct_type Any
|
66
|
-
assert_correct_type Any
|
67
|
-
assert_correct_type Any
|
67
|
+
assert_correct_type [Any >= Any], [@array ], @numeric
|
68
|
+
assert_correct_type [Any >= Any], [@string], @numeric
|
69
|
+
assert_correct_type [Any >= Any], [@hash ], @numeric
|
70
|
+
assert_correct_type [Any >= Any], [@symbol], @numeric
|
71
|
+
|
72
|
+
assert_correct_type [Any, Any >= Any], [@numeric, @array ], @numeric
|
73
|
+
assert_correct_type [Any, Any >= Any], [@numeric, @string], @numeric
|
74
|
+
assert_correct_type [Any, Any >= Any], [@numeric, @hash ], @numeric
|
75
|
+
assert_correct_type [Any, Any >= Any], [@numeric, @symbol], @numeric
|
68
76
|
end
|
69
77
|
|
70
78
|
private
|
@@ -89,7 +97,7 @@ class TestHaskell < MiniTest::Unit::TestCase
|
|
89
97
|
def call(#{arg_literal(args.count)})
|
90
98
|
#{obj_literal(val)}
|
91
99
|
end
|
92
|
-
type #{
|
100
|
+
type #{type_list.map(&:to_s).join(',')}, :call
|
93
101
|
RUBY_CODE
|
94
102
|
|
95
103
|
klass.new
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haskell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- gogotanaka
|
@@ -87,10 +87,7 @@ files:
|
|
87
87
|
- ext/haskell/haskell.h
|
88
88
|
- haskell.gemspec
|
89
89
|
- lib/haskell.rb
|
90
|
-
- lib/haskell/
|
91
|
-
- lib/haskell/assert_rtn_type.rb
|
92
|
-
- lib/haskell/base.rb
|
93
|
-
- lib/haskell/type_list.rb
|
90
|
+
- lib/haskell/type_pair.rb
|
94
91
|
- lib/haskell/version.rb
|
95
92
|
- test/minitest_helper.rb
|
96
93
|
- test/test_haskell.rb
|
@@ -1,14 +0,0 @@
|
|
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
|
@@ -1,16 +0,0 @@
|
|
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
DELETED
data/lib/haskell/type_list.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# '>=' is left-associative ...
|
2
|
-
# List like LISP or Hash may be better.
|
3
|
-
class TypeList
|
4
|
-
attr_accessor :list
|
5
|
-
|
6
|
-
def initialize(l, r)
|
7
|
-
@list = [l, r]
|
8
|
-
end
|
9
|
-
|
10
|
-
def >=(r)
|
11
|
-
@list << r
|
12
|
-
self
|
13
|
-
end
|
14
|
-
|
15
|
-
def args
|
16
|
-
@list[0..-2]
|
17
|
-
end
|
18
|
-
|
19
|
-
def rtn
|
20
|
-
@list.last
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_s
|
24
|
-
@list.map(&:to_s).join(' -> ')
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class Module
|
29
|
-
def >=(r)
|
30
|
-
TypeList.new(self, r)
|
31
|
-
end
|
32
|
-
end
|