On Github parsonsmatt / currb
Just...
look around you!
Have you worked out what we're looking for?
invented by Moses Schönfinkel
(discovered by Hubert Kennedy)
First, you need a function
add = lambda do |x, y| x + y end add.call(5, 6)
More tersely,
add = -> x, y { x + y }
add[5, 6]
Now, instead of returning the value, wrap the value in a lambda.
add = lambda do |x, y|
lambda do
x + y
end
end
add.call(5, 6).call
Now, just move the argument from the outer lambda to the inner lambda!
add = lambda do |x|
lambda do |y|
x + y
end
end
add.call(5).call(6)
Y'all are curry masters!
foo = lambda do |x| 2 * x + 1 end bar = lambda do |x| x ** 2 end (foo * bar).call(x) == foo.call(bar.call(x))
Ruby doesn't have a function composition operator...
... yet!!
class Proc
def *(other)
lambda do |x|
self.call(other.call(x))
end
end
end
Bash pipes!
# How many classes are defined in your app? $ cat **/*.rb | grep "^class" | wc -l
# Using the * style: $ (wc -l * grep "^class" * cat)( **/*.rb ) $ wc -l ( grep "^class" ( cat ( **/*.rb ) ) )
Those Unix commands are partially applied!
$ wc -l **/*.rb $ grep "^class" **/*.rb $ cat **/*.rb
Unfortunately, Ruby doesn't have the pipe composition operator...
... yet!
class Proc
def |(other)
lambda do |x|
other.call(self.call(x))
end
end
end
function update(index, item) {
App.data[index] = item;
}
function renderItems() {
return App.data.map(function (item, index) {
return new Item(item, update.bind(this, index));
});
}
function update(index) {
return function (item) {
App.data[index] = item;
}
}
function renderItems() {
return App.data.map(function (item, index) {
return new Item(item, update(index));
});
}
let update = index => item => App.data[index] = item;
function renderItems() {
return App.data.map(
(item, index) => new Item(item, update(index))
);
}
add = -> x, y { x + y }
Java
public static int add(int x, int y) {
return x + y;
}
Haskell
add :: Int -> Int -> Int add x y = x + yMath $add : \mathbb{Z} \rightarrow \mathbb{Z} \rightarrow \mathbb{Z}$$ add(x, y) = x + y $
a transformation from something to some other thing
represented like: $$ A \rightarrow B $$
where $A$ is the type of the original thing, and $B$ is the type of the new thing, and the arrow ($\rightarrow$) represents the transformation
Ruby is Object Oriented, not Lambda or Function Oriented.
Is there an equivalence? How can we translate these ideas?
RCaaF -- startup idea!
(this is kinda out there so please stop me and ask questions if you want)
How to make a Ruby class like a function?
$$ f : A \rightarrow B $$Where:
A Duck is the methods we care about on some object.
class F
attr_reader :b
def initialize(object)
@b = object.a
end
end
Objects from F have the duck b, and it's input argument has the duck a
class G
attr_reader :a
def initialize(object)
@a = object
end
end
Objects from G have the duck a, and it's input argument doesn't have a duck
>> F.new( G.new( 5 ) ).b => 5
I wrote the gem Beethoven to make this sort of thing easier
The following are equivalent:
F.new(G.new(5)).b
(F * G).new(5).b
(G | F).new(5).b
[G, F].reduce(&:|).new(5)
Single argument functions are boring...
lambda do |x, y| x + y end.call(5, 6)to
lambda do |x|
lambda { |y| x + y }
end.call(5).call(6)
Class#new
class Add
def initialize(x)
@x = x
end
def new(y)
@y = y; return self
end
def value
@x + @y
end
end
>> Add.new(5).new(6).value => 11
class Map
def initialize(func)
@func = func
end
def new(object)
@list = object.list; self
end
def list
@list.map(&@func)
end
end
class Filter
def initialize(func)
@func = func
end
def new(object)
@list = object.list; self
end
def list
@list.filter(&@func)
end
end
class Reduce
def initialize(func)
@func = func
end
def new(object)
@list = object.list; self
end
def value
@list.reduce(&@func)
end
end
List = Struct.new(:list)
list = List.new( (1..100).to_a )
Reduce.new(-> sum, next { sum + next }).new(
Map.new(-> x { x + 10 }).new(
Filter.new(-> x { x.even? }).new(list)
)
).value
=> 3050
Pipeline = Filter.new(-> x { x.even? })
| Map.new(-> x { x + 10 })
| Reduce.new(-> sum, next { sum + next })
Pipeline.new(list).value
=> 3050
even = -> x { x.even? }
add_ten = -> x { x + 10 }
add = -> x, y { x + y }
Pipeline = Filter.new(even)
| Map.new(add_ten)
| Reduce.new(add)
Pipeline.new(list).value
=> 3050
even = -> x { x.even? }
add = -> x, y { x + y }.curry
Pipeline = Filter.new(even)
| Map.new(add.call(10))
| Reduce.new(add)
Pipeline.new(list).value
=> 3050
Ruby and JavaScript @(we're they're hiring!)
Now, Haskell @ Layer 3 Communications