Skip to content

Instantly share code, notes, and snippets.

@JoelQ
Last active June 30, 2021 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoelQ/b5356aaa80e2e032c6cabfe79d5d0da5 to your computer and use it in GitHub Desktop.
Save JoelQ/b5356aaa80e2e032c6cabfe79d5d0da5 to your computer and use it in GitHub Desktop.
Exploration of Knuth Arrows as monoids
class Add
def self.mempty
new(0)
end
def initialize(number)
@number = number
end
attr_reader :number
def mappend(other)
other.number.times.reduce(self) do |total|
Add.new(total.number.next)
end
end
def iterated(other)
other.number.times.reduce(self.class.mempty) do |total|
add1 = Add.new(total.number)
add2 = Add.new(number)
add1.mappend add2
end
end
end
class Multiply
def self.mempty
new(1)
end
def initialize(number)
@number = number
end
attr_reader :number
def mappend(other)
product = Add.new(number).iterated(Add.new(other.number))
Multiply.new(product.number)
end
def iterated(other)
other.number.times.reduce(self.class.mempty) do |total|
mult1 = Multiply.new(total.number)
mult2 = Multiply.new(number)
mult1.mappend mult2
end
end
end
class Exponent
def self.mempty
new(1)
end
def initialize(number)
@number = number
end
attr_reader :number
def mappend(other)
exponent = Multiply.new(number).iterated(Multiply.new(other.number))
Exponent.new(exponent.number)
end
end
class Increment
def initialize(number = 0)
@number = number
end
attr_reader :number
def next
Addition.new(number, self)
end
def iterated(other)
Addition.new(
other.number.times.reduce(number) { |total| total.next },
self
)
end
end
class Knuth
def self.number(number)
Increment.new(number)
end
def self.enumerator(n=0)
Enumerator.new do |y|
(1..Float::INFINITY).reduce(number n) do |total|
y << total
total.next
end
end
end
def self.nth(n)
enumerator.take(n).last
end
def initialize(number, previous)
@number = number
@previous = previous
end
def next
Knuth.new(number, self)
end
attr_reader :previous, :number
def mempty
self.class.new(1, previous)
end
def mappend(other)
previous.iterated(other)
end
def iterated(other)
self.class.new(
other.number.times.reduce(mempty) { |total| mappend(total) }.number,
self
)
end
end
class Addition < Knuth
def mempty
self.class.new(0, previous)
end
end
@JoelQ
Copy link
Author

JoelQ commented Jun 30, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment