console.log('_________CHALLENGE 01________');
let add = (a,b)=>a+b;
let mul = (a,b)=>a*b;
let sub = (a,b)=>a-b;
console.log('sum:',add(3,4));
console.log('mul:',mul(3,4));
console.log('sub:',sub(3,4));
let identityf = a=>()=>a;// same as function(a){retunr function(){return a;};}
let three = identityf(3);
console.log('three exec:',three());
let addf = a=>{
return function(b){
return a+b;
};
};
console.log('addf:',addf(3)(4));
let liftf = function(binaryFunc){
return function(a){
return function(b){
return binaryFunc(a,b);
};
};
};
let add2 = liftf(add);
console.log('liftf:',add2(3)(4));
/////////////////////////////////////////challenge 2///////////////////////////////
console.log('_________CHALLENGE 02________');
//let curry = function(binaryFunc, a){
// return function(b){
// return binaryFunc(a,b)
// }
//}
let curry = (bFunc, a)=> liftf(bFunc)(a);
let add3 = curry(add,3);
console.log('add3:',add3(5));
//let inc = addf(1);
//let inc = liftf(add)(1);
let inc = curry(add,1);
console.log('inc:',inc(inc(5)));
////////////////////challenge 3////////////////////////////
console.log('_________CHALLENGE 03________');
let twice = bf=>(a)=>bf(a,a);
let doubl = twice(add);
let square = twice(mul);
console.log('twice:',doubl(3));
console.log('twice2:',square(3));
let reverse = bf=>(a,b)=>bf(b,a);
let bus = reverse(sub);
console.log('reverse:',bus(2,3));
let composeu = (ufa, ufb)=>a=>ufb(ufa(a));
console.log('compose U:',composeu(doubl, square)(5));
let composeb = (bfa,bfb)=>(a,b,c)=>bfb(bfa(a,b),c);
console.log('compose B:', composeb(add, mul)(2,3,7));
let limit = (func, count)=>{
return function (a,b){
if (count){
count-=1;
return func(a,b);
}else{
return undefined;
}
};
};
let limitedAdd = limit(add,1);
console.log('limitedAdd 1:',limitedAdd(2,3));
console.log('limitedAdd 2:',limitedAdd(3,4));
console.log('limitedAdd 3:',limitedAdd(3,4));
////////////////////////challenge 04///////////////////////////////
console.log('_________CHALLENGE 04________');
let from = arg=>{
return ()=>{
let buffer = arg;
arg+=1;
return buffer;
};
};
let index = from(0);
console.log('call 01 of index:',index());
console.log('call 02 of index:',index());
console.log('call 03 of index:',index());
let to = (generator, limit)=>{
return ()=>{
let x = generator();
if (x<limit){
return x;
}
return undefined;
};
};
let limitedIndex = to(from(1), 3);
console.log('call 01 of limited index:', limitedIndex());
console.log('call 02 of limited index:', limitedIndex());
console.log('call 03 of limited index:', limitedIndex());
let fromTo = (a, b)=>{
return to(from(a), b);
};
let fromToIndex = fromTo(0, 3);
console.log('call 01 of fromTo index:', fromToIndex());
console.log('call 02 of fromTo index:', fromToIndex());
console.log('call 03 of fromTo index:', fromToIndex());
console.log('call 04 of fromTo index:', fromToIndex());
let element = (arr, gen)=>{
return ()=>{
let index = gen();
if(index!==undefined){
return arr[index];
}
return undefined;
};
};
let ele = element(['a','b','c','d'],fromTo(1, 3));
console.log('call 01 of element:', ele());
console.log('call 02 of element:', ele());
console.log('call 03 of element:', ele());
let elementV2 = (arr, gen)=>{
if (gen ===undefined){
gen = fromTo(0,arr.length);
}
return element(arr, gen);
};
let eleV2 = elementV2(['a','b','c','d']);
console.log('call 01 of elementV2:', eleV2());
console.log('call 02 of elementV2:', eleV2());
console.log('call 03 of elementV2:', eleV2());
console.log('call 04 of elementV2:', eleV2());
console.log('call 05 of elementV2:', eleV2());
////////////////////////challenge 05///////////////////////////////
console.log('_________CHALLENGE 05________');
let collect = (gen,arr)=>{
return ()=>{
let buffer = gen();
if (buffer!== undefined){
arr.push(buffer);
}
return buffer;
}
};
let array =[];
let col = collect(fromTo(0,2),array);
console.log('call 01 of collector:', col());
console.log('call 02 of collector:', col());
console.log('call 03 of collector:', col());
console.log('call 04 of collector:', col());
console.log('array:', array);
//Write a filter function that takes a generator and a predicate and produces a generator that produces only the values approved by the predicate.
let filter = (gen, pred)=>{
return ()=>{
let value = gen();
while(!pred(value) && value!==undefined){
value = gen();
}
return value;
};
};
let fil = filter (fromTo(0,5), value=>{return value%3===0;});
console.log('call 01 of filter:', fil());
console.log('call 02 of filter:', fil());
console.log('call 03 of filter:', fil());
console.log('call 04 of filter:', fil());
//Write a concat function that takes two generators and produces a generator that combines the sequences
let concat = (gen1, gen2)=>{
return ()=>{
let buffer = gen1();
if (buffer !== undefined){
return buffer
}
return gen2();
}
};
let con = concat (fromTo(0,3), fromTo(0,2));
console.log('call 01 of concat:', con());
console.log('call 02 of concat:', con());
console.log('call 03 of concat:', con());
console.log('call 04 of concat:', con());
console.log('call 05 of concat:', con());
console.log('call 06 of concat:', con());
////////////////////////challenge 06///////////////////////////////
console.log('_____________CHALLENGE 06_____________');
//Make a function gensymf that makes a function that generates unique symbols
let gensymf = symbol=>{
let count = 0;
return ()=>{
count += 1;
return symbol.toString()+count
};
};
let geng = gensymf('G');
let genh = gensymf('H');
console.log('call 01 of geng:', geng());
console.log('call 01 of genh:', genh());
console.log('call 02 of geng:', geng());
console.log('call 02 of genh:', genh());
//Make a function fibonaccif that returns a generator that will return the next fibonacci number
let fibonaccif = (a, b)=>{
return ()=>{
let next = a;
a = b;
b+= next;
return next;
}
}
let fib = fibonaccif(0,1);
console.log('call 01 of fib:', fib());
console.log('call 02 of fib:', fib());
console.log('call 03 of fib:', fib());
console.log('call 04 of fib:', fib());
console.log('call 05 of fib:', fib());
console.log('call 06 of fib:', fib());