diff options
Diffstat (limited to 'patter.rb')
-rw-r--r-- | patter.rb | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/patter.rb b/patter.rb new file mode 100644 index 0000000..348cbdf --- /dev/null +++ b/patter.rb @@ -0,0 +1,43 @@ +module Patter + class Var; end + + class Fun + def initialize + @patterns = {} + end + + def when(*args, &block) + raise "Block arity does not match number of free variables" if args.count(Var) != block.arity + @patterns[args] = block + end + + def call(*args) + free_vars, block = match(args) + block.call(*free_vars) + end + + alias_method :[], :call + + private + + def match(args) + @patterns.each do |pattern, block| + next if pattern.length != args.length + free_variables = [] + matched = true + pattern.zip(args).each do |pair| + if pair.first == Var then + free_variables << pair.last + next + end + if pair.first != pair.last then + matched = false + break + end + end + return [free_variables, block] if matched + end + raise "Inexhaustive patterns" + end + end +end |