haskell 0.0.3 → 0.1.0
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/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
|