JavaScript анонимная функция, имитирующая арифметику c в лямбда-исчислении, результат возвращает `undefined` - PullRequest
0 голосов
/ 05 января 2020

Я должен был использовать javascript замыкание для имитации базисного c арифметического c в лямбда-исчислении, чтобы определить 3 = 1 + 2 следующим образом:

0 := λf.λx.x
1 := λf.λx.f x
2 := λf.λx.f (f x)
3 := λf.λx.f (f (f x))

Он должен печататься три раза hello world, теперь он печатает один раз hello world и дважды undefined. Может ли кто-нибудь помочь объяснить, почему это произошло и что случилось с моим кодом? Заранее спасибо.

var zero = function(f) {
  return function(x) {
    return x;
  };
};

var one = function(f) {
  return function(x) {
    return f(x);
  };
};

function add(n, m) {
  return function(f) {
    return function(x) {
      return n(f)(m(f)(x));
    };
  };
}

// test, define number two and number three in lambda calculus
var two = add(one, one);
var three = add(one, two);

// function f is to console.log
var print3times = three(value => console.log(value));
print3times("hello world")
// return:
// hello world
// undefined
// undefined

Ответы [ 3 ]

2 голосов
/ 05 января 2020

Вот ты go.

var log = function(x) {
  console.log(x)
  return x
}

var zero = function(f) {
  return function(x) {
    return x;
  };
};

var one = function(f) {
  return function(x) {
    return f(x);
  };
};

function add(n, m) {
  return function(f) {
    return function(x) {
      return n(f)(m(f)(x));
    };
  };
}

// test, define number two and number three in lambda calculus
var two = add(one, one);
var three = add(one, two);

// function f is to console.log
var print3times = three(log);
print3times("hello world")

Вот перевод ES6 с несколькими бонусными функциями для развлечения:

const log = x => (console.log(x), x)

const identity = x => x
const compose = f => g => x => f(g(x))

const zero = f => identity

const one = f => x => f(x)

// I took the liberty of currying add
const add = n => m => f => x => n(f)(m(f)(x))

// test, define number two and number three in lambda calculus
const addOne = add(one)
const two = addOne(one)
const three = addOne(two)
const four = compose(addOne)(addOne)(two)

// function f is to console.log
const print3times = three(log)
print3times("hello world")

four(log)('hi X 4')

Также вы можете найти эти два видео на YouTube под названием «Стая функций: комбинаторы, лямбда-исчисление и церковные кодировки в JS», информативные: Часть 1 , часть 2 .

1 голос
/ 05 января 2020

Вы, кажется, думаете, что three(value => console.log(value)) сделает это:

function(value) {
    console.log(value);
    console.log(value);
    console.log(value);
}

Но это не так. Он действительно сделает это:

function(value) {
    console.log(console.log(console.log(value)));
}

Другими словами, все ваши комбинаторы лямбда-исчисления все в порядке; вы просто неправильно их используете.

1 голос
/ 05 января 2020

Дело в том, что m (f) (x) в n (f) (m (f) (x)) возвращает undefined, поскольку это console.log. Затем он запускает его первым (и печатает «hello world»), но при запуске n (f) на нем он печатает результат m (f) (x): undefined. Как заявлено ASDFGerte, если вы добавите «возвращаемое значение»; к этому. Это будет работать правильно.

...