Skip to content

Instantly share code, notes, and snippets.

@ifyouseewendy
Created June 18, 2015 07:35
Show Gist options
  • Save ifyouseewendy/f8b42885cf6da6b5a473 to your computer and use it in GitHub Desktop.
Save ifyouseewendy/f8b42885cf6da6b5a473 to your computer and use it in GitHub Desktop.
A stack implementation from http://codon.com/refactoring-ruby-with-monads
# API
#
# + push
# + top
# + pop
# + empty
# + empty?
ArrayStack = Struct.new(:values) do
def push(value)
ArrayStack.new([value] + values)
end
def top
values.first
end
def pop
ArrayStack.new(values.drop(1))
end
def ==(other)
return false unless top == other.top
return true if empty? && other.empty?
self.pop == other.pop
end
def empty?
values.empty?
end
def self.empty
new([])
end
end
LinkedListStack = Struct.new(:top, :pop) do
def push(value)
LinkedListStack.new(value, self)
end
def empty?
top.nil?
end
def ==(other)
return false unless top == other.top
return true if empty? && other.empty?
self.pop == other.pop
end
def self.empty
new(nil, nil)
end
end
require 'minitest/autorun'
module StackTest
def test_top
@stack.push('a').top == 'a'
end
def test_pop
@stack.push('a').pop == @stack
end
def test_empty?
refute @stack.push('a').empty?
end
def test_empty
assert @stack.class.empty.empty?
end
end
class ArrayStackTest < MiniTest::Unit::TestCase
include StackTest
def setup
@stack = ArrayStack.new([1,2,3])
end
end
class LinkedListStackTest < MiniTest::Unit::TestCase
include StackTest
def setup
@stack = LinkedListStack.new([1,2,3])
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment