lib/haskell.rb in haskell-0.0.3 vs lib/haskell.rb in haskell-0.1.0
- old
+ new
@@ -1,30 +1,49 @@
-require 'haskell/type_list'
-require 'haskell/base'
-require 'haskell/assert_arg_type'
-require 'haskell/assert_rtn_type'
+require 'haskell/type_pair'
-module Haskell; end
-
-# New Class(Type)
+# Builtin Contracts
class Any; end
module Boolean; end
TrueClass.send(:include, Boolean)
FalseClass.send(:include, Boolean)
class Module
private
- def __haskell__
- prepend (@__haskell__ = Module.new) unless @__haskell__
- @__haskell__
+ def __haskell__
+ prepend (@__haskell__ = Module.new) unless @__haskell__
+ @__haskell__
+ end
+
+ def type(*arguments)
+ *arg_types, type_pair, meth = arguments
+
+ __haskell__.send(:define_method, meth) do |*args, &block|
+ ::Haskell.assert_arg_type(meth, args, arg_types << type_pair.last_arg_type)
+ rtn = super(*args, &block)
+ ::Haskell.assert_trn_type(meth, rtn, type_pair.rtn_type)
+ rtn
end
+ self
+ end
+end
- def type(type_list, meth)
- __haskell__.send(:define_method, meth) do |*args, &block|
- ::Haskell::AssertArgType.execute(meth, args, type_list.args)
- rtn = super(*args, &block)
- ::Haskell::AssertRtnType.execute(meth, rtn, type_list.rtn)
- rtn
+module Haskell
+ class << self
+ def assert_arg_type(meth, args, klasses)
+ args.each_with_index do |arg, i|
+ if wrong_type?(arg, klasses[i])
+ raise ArgumentError, "Wrong type of argument, type of #{arg.inspect} should be #{klasses[i]}"
+ end
end
- self
end
+
+ def assert_trn_type(meth, rtn, klass)
+ if wrong_type?(rtn, klass)
+ raise TypeError, "Expected #{meth} to return #{klass} but got #{rtn.inspect} instead"
+ end
+ end
+
+ def wrong_type?(obj, klass)
+ !(obj.is_a?(klass) || klass == Any)
+ end
+ end
end