|
|
@@ -0,0 +1,204 @@ |
|
|
/* |
|
|
* @link https://frontendmasters.com/courses/javascript-the-good-parts/ |
|
|
Problems 1-5 |
|
|
A sequence of problems will be presented followed by a solution. Each problem builds on the last so if you get a problem wrong, use the solution to begin the next problem. First, a quick quiz: What is x? |
|
|
3:19:33 - 3:32:25 |
|
|
Problems 6-9 |
|
|
o Problem 6: Write a function that takes a function and an argument, and returns a function that can supply a second argument. |
|
|
o Problem 7: Without writing any new functions, show three ways to create the inc function. |
|
|
o Problem 8: Write methodize, a function that converts a binary function to a method. |
|
|
o Problem 9: Write demethodize, a function that converts a method to a binary function. |
|
|
3:32:26 - 3:37:26 |
|
|
Problems 10-12 |
|
|
o Problem 10: Write a function twice that takes a binary function and returns a unary function that passes its argument to the binary function twice. |
|
|
o Problem 11: Write a function compseu that takes two unary functions and returns a unary function that calls both of them. |
|
|
o Problem 12: Write a function compseb that takes two binary functions and returns a function that calls both of them. |
|
|
3:37:27 - 3:48:54 |
|
|
Problems 13-15 |
|
|
o Problem 13: Write a function that allows another function to only be called once. |
|
|
o Problem 14: Write a factory function that returns two functions that implement an up/down counter. |
|
|
o Problem 15: Make a revocable function that takes a nice function, and returns a revoke function that denies access to the nice function, and an invoke function that can invoke the nice function until it’s revoked. |
|
|
|
|
|
/*/ |
|
|
|
|
|
|
|
|
function identity(v) { |
|
|
return v; |
|
|
} |
|
|
|
|
|
identity(3); |
|
|
|
|
|
function add(x, y) { |
|
|
return x + y; |
|
|
} |
|
|
|
|
|
function mul(x, y) { |
|
|
return x * y; |
|
|
} |
|
|
|
|
|
function identityf(x) { |
|
|
return function() { |
|
|
return x; |
|
|
} |
|
|
} |
|
|
|
|
|
function addf(x) { |
|
|
return function(y) { |
|
|
return x + y; |
|
|
} |
|
|
} |
|
|
|
|
|
function applyf(binary) { |
|
|
return function(x){ |
|
|
return function(y) { |
|
|
return binary(x, y); |
|
|
} |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
function curry(func, first) { |
|
|
return function (second) { |
|
|
return func(first, second); |
|
|
} |
|
|
} |
|
|
|
|
|
add3 = curry(add, 3); |
|
|
add3(4); |
|
|
|
|
|
curry(mul, 5)(6); |
|
|
|
|
|
function inc(x) { |
|
|
return addf(1); |
|
|
} |
|
|
// function inc(x) { |
|
|
// return applyf(add)(1); |
|
|
// } |
|
|
// function inc(x) { |
|
|
// return curry(add,1); |
|
|
// } |
|
|
function methodize(func) { |
|
|
return function(x) { |
|
|
return func(this, x); //Uses the prototype //I didn't |
|
|
}; |
|
|
} |
|
|
|
|
|
function demethodize(func) { |
|
|
return function (that, y) { |
|
|
return func.call(that, y); //I didn't |
|
|
}; |
|
|
} |
|
|
Number.prototype.add = methodize(add); |
|
|
Number.prototype.mul = methodize(mul); |
|
|
demethodize(Number.prototype.add)(5, 6); |
|
|
|
|
|
//Write a function twice that takes a binary function and |
|
|
//returns a unary function that passes its argument |
|
|
//to the binay function twice |
|
|
function twice(binary) { |
|
|
return function (a) { //unary function |
|
|
return binary(a, a); |
|
|
} |
|
|
} |
|
|
|
|
|
var double = twice(add); |
|
|
double(11); |
|
|
var square = twice(mul); |
|
|
square(11); |
|
|
|
|
|
//Write a function composeu that takes two unacty functions |
|
|
//and returns a unary function that calls the both |
|
|
function composeu(func1, func2) { |
|
|
return function(x) { |
|
|
return func2(func1(x)); |
|
|
} |
|
|
} |
|
|
|
|
|
composeu(double,square)(3); //36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Write a function composeb that takes two binary functions and |
|
|
//returns a function that calls them both. |
|
|
function composeb(func1, func2) { |
|
|
return function(x, y, z) { |
|
|
return func2( func1(x, y), z); |
|
|
} |
|
|
} |
|
|
composeb(add, mul)(2,3,5) //25 |
|
|
|
|
|
//Write a function that allows another function to only be called once. |
|
|
|
|
|
function once(func) { |
|
|
return function() { |
|
|
var f = func; |
|
|
func = null; |
|
|
return f.apply( |
|
|
this, |
|
|
arguments //I didn't do nothing similar. that was a hard one. |
|
|
); |
|
|
}; |
|
|
} |
|
|
|
|
|
add_once = once(add); |
|
|
add_once(3, 4); //7 |
|
|
// add_once(3, 4); //throw error |
|
|
|
|
|
//Write a factory function that returns two functions |
|
|
//that implement an up/down counter. //My worked well |
|
|
var counterf = function(x) { |
|
|
return { |
|
|
inc: function() { |
|
|
x += 1; |
|
|
return x; |
|
|
}, |
|
|
dec: function() { |
|
|
x -= 1 |
|
|
return x; |
|
|
} |
|
|
}; |
|
|
|
|
|
}; |
|
|
counter = counterf(10); |
|
|
counter.inc(); |
|
|
counter.dec(); |
|
|
|
|
|
//Make a revocable function that takes a nice function, |
|
|
//and returns a revoke function that denies access to the nice function, |
|
|
//and an invoke function that can invoke the nice function until is revoked. |
|
|
//I did it by myself and worked :D, but I'll let bellow the changes that he used |
|
|
|
|
|
// var revocable = function(func) { //Work just fine, but different from Douglas |
|
|
// var f = func; |
|
|
// return { |
|
|
// invoke: function(value) { |
|
|
// return func(value); |
|
|
// }, |
|
|
// revoke: function() { |
|
|
// func = null; |
|
|
// } |
|
|
// }; |
|
|
// }; |
|
|
function revocable(nice) { |
|
|
return { |
|
|
invoke: function() { //don't need parameters when apply with arguments |
|
|
return nice.apply(this, arguments); |
|
|
}, |
|
|
revoke: function() { |
|
|
nice = null; |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
var myAlert = function(v) { |
|
|
return alert(v); |
|
|
} |
|
|
|
|
|
temp = revocable(myAlert); //alert doesn't work with apply() |
|
|
temp.invoke(7); //alert 7 |
|
|
temp.invoke(8); //alert 7 |
|
|
temp.revoke(); |
|
|
temp.invoke(9); //throw error |
|
|
|
|
|
|