如何实现对应用性计算的协同程序?

问题描述 投票:3回答:1

这里要说的是避免了嵌套图案像(chain(m) (chain(...))为一元计算的协程:

const some = x => none => some => some(x);
const none = none => some => none;

const option = none => some => tx => tx(none) (some);
const id = x => x;

const of = some;
const chain = fm => m => none => some => m(none) (x => fm(x) (none) (some));

const doM = (chain, of) => gf => {
  const it = gf();

  const loop = ({done, value}) =>
    done
      ? of(value)
      : chain(x => loop(it.next(x))) (value);

  return loop(it.next());
};

const tx = some(4),
  ty = some(5),
  tz = none;

const data = doM(chain, of) (function*() {
  const x = yield tx,
    y = yield ty,
    z = yield tz;

  return x + y + z;
});

console.log(
  option(0) (id) (data)); // 0

但我没能实现对应用性的计算等效协程:

const some = x => none => some => some(x);
const none = none => some => none;

const option = none => some => tx => tx(none) (some);
const id = x => x;

const of = some;
const map = f => t => none => some => t(none) (x => some(f(x)));
const ap = tf => t => none => some => tf(none) (f => t(none) (x => some(f(x))));

const doA = (ap, of) => gf => {
  const it = gf();

  const loop = ({done, value}, initial) =>
    done
      ? value
      : ap(of(x => loop(it.next(x)))) (value);

  return loop(it.next());
};

const tx = some(4),
  ty = some(5),
  tz = none;

const data = doA(ap, of) (function*() {
  const x = yield tx,
    y = yield ty,
    z = yield tz;

  return x + y + z;
});

console.log(
  option(0) (id) (data)); // none => some => ...

这应该工作,但事实并非如此。哪里额外函子包装从何而来?我猜我有点在递归失去了这里。

顺便说一句,我知道,这仅适用于确定性的函子/单子。

javascript functional-programming monads functor applicative
1个回答
2
投票

我不能够实现对应用性的计算等效协程

是的,因为发电机的功能是一元,而不仅仅是应用性。一个yield表达的操作数可以依赖于以前的yield表达式的结果 - 这是一个单子的特性。

哪里额外函子包装从何而来?我想我在这里有点失落。

你正在做ap(of(…))(…) - 这相当于根据map(…)(…)Applicative laws。相比于第一片段的chain通话,这并不做结果的任何解缠,让你得到一个嵌套maybe类型(在您的实现,被编码为一个功能)。

© www.soinside.com 2019 - 2024. All rights reserved.