下面是一种避免像嵌套图案的协程(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 => ...
这应该工作,但事实并非如此。哪里额外函子包装从何而来?我想我在递归中有点迷路了。
据我所知,这仅适用于确定性函子/单子。
答案 0 :(得分:2)
我无法为应用计算实现等效的协程
是的,因为生成器函数是一元函数,而不仅仅是适用函数。一个#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main() {
char* arr[2][2];
char str[20];
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("%s", "please put in a string: ");
if (scanf("%s", &str[0]) == 1)
{
arr[i][j] = (char*)malloc(20*sizeof(char));
strncpy(arr[i][j], str, 20);
}
}
}
for(int i = 0; i < 2; i++){
for (int j = 0; j < 2; j++){
printf("arr[%d][%d] == %s\n", i,j, arr[i][j]);
}
}
return 0;
}
表达式的操作数可以取决于先前的yield
表达式的结果 - ,对于一个单子的特性
附加函子包装来自何处?我想我在这里有点迷路了。
您正在做yield
-根据Applicative laws,这相当于ap(of(…))(…)
。与第一个代码段中的map(…)(…)
调用相比,此操作不会对结果进行任何拆包,因此您获得了嵌套的chain
类型(在您的实现中被编码为一个函数)。>