module Deterministic
TODO: remove dead code
Constants
- Option
- Result
- VERSION
Public Class Methods
guard_context(obj, args)
click to toggle source
# File lib/deterministic/enum.rb, line 155 def self.guard_context(obj, args) if obj.is_a?(Deterministic::EnumBuilder::DataType::Binary) Struct.new(*(args)).new(*(obj.value.values)) else Struct.new(*(args)).new(obj.value) end end
match(obj, &block)
click to toggle source
# File lib/deterministic/enum.rb, line 116 def self.match(obj, &block) caller_ctx = block.binding.eval 'self' matcher = self::Matcher.new(obj) matcher.instance_eval(&block) variants_in_match = matcher.matches.collect {|e| e[1].name.split('::')[-1].to_sym}.uniq.sort variants_not_covered = variants - variants_in_match raise Enum::MatchError, "Match is non-exhaustive, #{variants_not_covered} not covered" unless variants_not_covered.empty? type_matches = matcher.matches.select { |r| r[0].is_a?(r[1]) } type_matches.each { |match| obj, type, block, args, guard = match if args.count == 0 return caller_ctx.instance_eval(&block) else if args.count != obj.args.count raise Enum::MatchError, "Pattern (#{args.join(', ')}) must match (#{obj.args.join(', ')})" end guard_ctx = guard_context(obj, args) if guard if guard_ctx.instance_exec(obj, &guard) return caller_ctx.instance_exec(* obj.wrapped_values, &block) end else return caller_ctx.instance_exec(* obj.wrapped_values, &block) end end } raise Enum::MatchError, "No match could be made" end
new(obj)
click to toggle source
# File lib/deterministic/enum.rb, line 169 def initialize(obj) @obj = obj @matches = [] @vars = [] end
variants()
click to toggle source
# File lib/deterministic/enum.rb, line 152 def self.variants; constants - [:Matcher, :MatchError]; end
Public Instance Methods
+(other)
click to toggle source
# File lib/deterministic/option.rb, line 65 def +(other) match { None() { other } Some(where { !other.is_a?(Option) }) {|_| raise TypeError, "Other must be an #{Option}"} Some(where { other.some? }) {|s| Option::Some.new(s + other.value) } Some() {|_| self } } end
Left(value)
click to toggle source
# File lib/deterministic/either.rb, line 28 def Left(value) Either.new(Array[value], []) end
Right(value)
click to toggle source
# File lib/deterministic/either.rb, line 32 def Right(value) Either.new([], Array[value]) end
and(other)
click to toggle source
# File lib/deterministic/result.rb, line 62 def and(other) raise Deterministic::Monad::NotMonadError, "Expected #{other.inspect} to be a Result" unless other.is_a? Result match { Success() {|_| other } Failure() {|_| self } } end
enum(&block)
click to toggle source
# File lib/deterministic/enum.rb, line 112 def enum(&block) mod = Class.new do # the enum to be built class << self; private :new; end def self.match(obj, &block) caller_ctx = block.binding.eval 'self' matcher = self::Matcher.new(obj) matcher.instance_eval(&block) variants_in_match = matcher.matches.collect {|e| e[1].name.split('::')[-1].to_sym}.uniq.sort variants_not_covered = variants - variants_in_match raise Enum::MatchError, "Match is non-exhaustive, #{variants_not_covered} not covered" unless variants_not_covered.empty? type_matches = matcher.matches.select { |r| r[0].is_a?(r[1]) } type_matches.each { |match| obj, type, block, args, guard = match if args.count == 0 return caller_ctx.instance_eval(&block) else if args.count != obj.args.count raise Enum::MatchError, "Pattern (#{args.join(', ')}) must match (#{obj.args.join(', ')})" end guard_ctx = guard_context(obj, args) if guard if guard_ctx.instance_exec(obj, &guard) return caller_ctx.instance_exec(* obj.wrapped_values, &block) end else return caller_ctx.instance_exec(* obj.wrapped_values, &block) end end } raise Enum::MatchError, "No match could be made" end def self.variants; constants - [:Matcher, :MatchError]; end private def self.guard_context(obj, args) if obj.is_a?(Deterministic::EnumBuilder::DataType::Binary) Struct.new(*(args)).new(*(obj.value.values)) else Struct.new(*(args)).new(obj.value) end end end enum = EnumBuilder.new(mod) enum.instance_eval(&block) type_variants = mod.constants matcher = Class.new { def initialize(obj) @obj = obj @matches = [] @vars = [] end attr_reader :matches, :vars def where(&guard) guard end type_variants.each { |m| define_method(m) { |guard = nil, &block| raise ArgumentError, "No block given to `#{m}`" if block.nil? params_spec = block.parameters if params_spec.any? {|spec| spec.size < 2 } raise ArgumentError, "Unnamed param found in block parameters: #{params_spec.inspect}" end if params_spec.any? {|spec| spec[0] != :req && spec[0] != :opt } raise ArgumentError, "Only :req & :opt params allowed; parameters=#{params_spec.inspect}" end args = params_spec.map {|spec| spec[1] } type = Kernel.eval("#{mod.name}::#{m}") if guard && !guard.is_a?(Proc) guard = nil end @matches << [@obj, type, block, args, guard] } } } mod.const_set(:Matcher, matcher) type_variants.each { |variant| mod.singleton_class.class_exec { define_method(variant) { |*args| const_get(variant).new(*args) } } } mod end
failure?()
click to toggle source
# File lib/deterministic/result.rb, line 50 def failure? is_a? Result::Failure end
fmap(&fn)
click to toggle source
# File lib/deterministic/option.rb, line 30 def fmap(&fn) match { Some() {|s| self.class.new(fn.(s)) } None() { self } } end
impl(enum_type, &block)
click to toggle source
# File lib/deterministic/enum.rb, line 216 def impl(enum_type, &block) enum_type.variants.each { |v| name = "#{enum_type.name}::#{v.to_s}" type = Kernel.eval(name) type.class_eval(&block) } end
instance(protocol, type, &block)
click to toggle source
# File lib/deterministic/protocol.rb, line 94 def instance(protocol, type, &block) InstanceBuilder.new(protocol, type, block).build end
map(&fn)
click to toggle source
# File lib/deterministic/option.rb, line 37 def map(&fn) match { Some() {|s| self.bind(&fn) } None() { self } } end
map_err(proc=nil, &block)
click to toggle source
# File lib/deterministic/result.rb, line 30 def map_err(proc=nil, &block) match { Success() {|_| self } Failure() {|_| self.bind(proc|| block) } } end
Also aliased as: or_else
none?()
click to toggle source
# File lib/deterministic/option.rb, line 48 def none? is_a? Option::None end
Also aliased as: empty?
or(other)
click to toggle source
# File lib/deterministic/result.rb, line 54 def or(other) raise Deterministic::Monad::NotMonadError, "Expected #{other.inspect} to be a Result" unless other.is_a? Result match { Success() {|_| self } Failure() {|_| other } } end
pipe(proc=nil, &block)
click to toggle source
# File lib/deterministic/result.rb, line 39 def pipe(proc=nil, &block) (proc || block).call(self) self end
Also aliased as: <<
protocol(typevar, &block)
click to toggle source
# File lib/deterministic/protocol.rb, line 88 def protocol(typevar, &block) protocol = ProtocolBuilder.new(typevar, block).build p_module = block.binding.eval('self') p_module.const_set(:Protocol, protocol) end
some?()
click to toggle source
# File lib/deterministic/option.rb, line 44 def some? is_a? Option::Some end
success?()
click to toggle source
# File lib/deterministic/result.rb, line 46 def success? is_a? Result::Success end
try(proc=nil, &block)
click to toggle source
# File lib/deterministic/result.rb, line 80 def try(proc=nil, &block) map(proc, &block) rescue => err Result::Failure.new(err) end
Also aliased as: >=
value_or(n)
click to toggle source
# File lib/deterministic/option.rb, line 54 def value_or(n) match { Some() {|s| s } None() { n } } end
value_to_a()
click to toggle source
# File lib/deterministic/option.rb, line 61 def value_to_a @value end
where(&guard)
click to toggle source
# File lib/deterministic/enum.rb, line 177 def where(&guard) guard end