Übung 03 - JavaScript
3.1 Funktionen in JavaScript
Schreiben Sie eine Funktion identity_function(), die ein Argument als Parameter entgegen
nimmt und eine Funktion zurück gibt, die dieses Argument zurück gibt.
function identity_function(param){
return function(){
return param;
}
}
Schreiben Sie eine Addier-Funktion addf(), so dass addf(x)(y) genau x + y zurück gibt.
function addf(x){
return function(y){
return x+y;
}
}
Schreiben Sie eine Funktion applyf(), die aus einer binären Funktion wie add(x,y) eine
Funktion
addf berechnet, die mit zwei Aufrufen das gleiche Ergebnis liefert.
function applyf(f){
return function(x){
return function(y){
return f(x,y);
}
}
}
Schreiben Sie eine Funktion curry(), die eine binäre Funktion und ein Argument
nimmt, um daraus eine Funktion zu erzeugen, die ein zweites Argument entgegen nimmt.
function curry(f, arg){
return function (argtwo){
return f(arg, argtwo)
}
}
Erzeugen Sie die inc-Funktion mit Hilfe einer der Funktionen addf, applyf und curry
aus den
letzten Aufgaben, ohne die Funktion inc() selbst zu implementieren.
// Version 1
function inc1(arg){
return addf(arg)(1);
}
// Version 2
function inc2(arg){
return applyf(add)(arg)(1);
}
// Version 3
function inc3(arg){
return curry(add, arg)(1);
}
Schreiben Sie eine Funktion methodize(), die eine binäre Funktion (z.B. add, mul) in eine unäre
Methode verwandelt. Nach Number.prototype.add = methodize(add); soll (3).add(4) genau 7 ergeben.
function methodize(f){
return function(x){
return f(this,x)
}
}
Schreiben Sie eine Funktion demethodize(), die eine unäre Methode (z.B. add, mul) in eine
binäre Funktion umwandelt. demethodize(Number.prototype.add)(5, 6) soll 11 ergeben.
function demethodize(f){
return function(x, y){
return f.call(x,y);
}
}
Schreiben Sie eine Funktion twice(), die eine binäre Funktion in eine unäre Funktion umwandelt,
die den einen Parameter zweimal weiter reicht.
function twice(f){
return function(x){
return f(x,x);
}
}
Schreiben Sie eine Funktion composeu(), die zwei unäre Funktionen in eine einzelne unäre
Funktion transformiert, die beide nacheinander aufruft.
function composeu(f1, f2){
return function(x){
return f2(f1(x));
}
}
Schreiben Sie eine Funktion composeb(), die zwei binäre Funktionen in eine einzelne Funktion
transformiert, die beide nacheinander aufruft.
function composeb(f1, f2){
return function(x,y,z){
return f2(f1(x,y),z);
}
}
Schreiben Sie eine Funktion once(), die einer anderen Funktion nur einmal erlaubt, aufgerufen
zu werden.
function once(func) {
return function () {
var f = func;
func = null;
return f.apply(this, arguments);
};
}
3.2 Advanced Functional JavaScript Programming
Make a function that makes a publish/subscribe object. It will reliably deliver all
publications to all subscribers in the right order.
function pubsub(){
var subs = []
return {
subscribe: function (f){
subs.push(f);
},
publish: function (arg){
for(let s of subs){
s(arg);
}
}
}
}
Make a factory that makes functions that generate unique symbols.
function gensymf(sym) {
var counter = 0;
return function () {
counter = counter + 1;
return `${sym}${counter - 1}`;
}
}
Make a function that returns a function that will return the next fibonacci number.
function fibonaccif(x, y) {
return function() {
var next = x;
x = y;
y += next;
return next;
}
}
Write a function that adds from many invocations, until it sees an empty invocation.
function addg(a){
if(!a){
return undefined;
}
return function plus(b){
if(!b){
return a;
}
if(b){
a += b;
return plus;
}
}
}
Write a function that will take a binary function and apply it to many invocations.
function applyg(f) {
return function (a) {
if (!a) return a;
return function cont(b) {
if (!b) return a;
a = f(a, b);
return cont;
}
}
}
Write a function m that takes a value and an optional source string and returns them in an
object.
function m(value, source){
return {"value": value, "source": (source || value).toString()};
}
Write a function addm that takes two m objects and returns an m object.
function addm(m1, m2){
return m(m1.value+m2.value, m1.source + m2.source);
}
Write a function binarymf that takes a binary function and a string and returns a function that
acts on m objects.
function binarymf(f, s) {
return function (m1, m2) {
return m(f(m1.value, m2.value), `(${m1.value}${s}${m2.value})`);
}
}
Modify function binarymf so that the functions it produces can accept arguments that are either
numbers or m objects.
function binarymf2(f, s){
return function(m1, m2){
if(m1.value){
return m(f(m1.value, m2.value), `(${m1.value}${s}${m2.value})`);
}else{
return m(f(m1,m2), `(${m1}${s}${m2})`);
}
}
}
Write function unarymf, which is like binarymf except that it acts on unary functions.
function unarymf(f, s){
return function(a){
return m(f(a), `(${s} ${a})`);
}
}
Write a function that takes the lengths of two sides of a triangle and computes the length of
the hypotenuse. (Hint: c2 = a2 + b2)
function hyp(a, b) {
return Math.sqrt(square(a) + square(b));
}
Write a function that evaluates array expressions.
function exp(arr) {
function iter(subarr){
for(let i in subarr){
if(subarr[i] instanceof Array){
subarr[i] = iter(subarr[i]);
}else{
if(typeof subarr[1] === "number"){
return calc(subarr);
}
}
}
return subarr;
}
function calc(arri){
if(arri.length === 2){
return arri[0](arri[1]);
}
if(arri.length === 3){
return arri[0](arri[1], arri[2]);
}
}
while(arr.some(e => e instanceof Array)){
iter(arr);
}
return calc(arr);
}
Make a function that stores a value in a variable.
function store(n) {
variable = n;
}
Make a function that takes a binary function, two functions that provide operands, and a
function that takes the result.
function quatre(binary, op1, op2, res){
res(binary(op1, op2));
}
Make a function that takes a unary function, and returns a function that takes an argument and
a callback.
function unaryc(unary){
return function (arg, cb){
cb(unary(arg));
}
}
Make a function that takes a binary function, and returns a function that takes two arguments
and a callback.
function binaryc(binary){
return function (a, b, cb){
cb(binary(a,b));
}
}