我有以下段落的问题来自Learn You A Haskell(伟大的书imo,而不是贬低它):
一个很大的区别是右侧折叠在无限列表上工作,而左侧折叠不起作用!说白了,如果你在某个点拿一个无限列表并从右边折叠起来,你最终会到达列表的开头.但是,如果你在一个点上获得一个无限的列表,并且你试图从左边折叠起来,那么你永远不会达到目的!
我只是不明白这一点.如果你拿一个无限的列表并试图从右边折叠起来那么你将不得不从无穷远点开始,这就是没有发生(如果有人知道你能做到这一点的语言,请告诉:p ).至少,你必须根据Haskell的实现开始那里,因为在Haskell中,foldr和foldl不会采用一个参数来确定列表中应该开始折叠的位置.
我同意引用iff foldr和foldl接受确定列表中应该开始折叠的位置的参数,因为有意义的是,如果你采用无限列表并从定义的索引开始向右折叠它最终将终止,而它不会无论你从哪里开始左折; 你将向无限折叠.但是,foldr和foldl 不接受这个参数,因此引用没有意义.在Haskell中,无限列表上的左侧折叠和右侧折叠都不会终止.
我的理解是正确的还是我错过了什么?
我有这个递归发生器
var obj = [1,2,3,[4,5,[6,7,8],9],10]
function *flat(x) {
if (Array.isArray(x))
for (let y of x)
yield *flat(y)
else
yield 'foo' + x;
}
console.log([...flat(obj)])Run Code Online (Sandbox Code Playgroud)
它工作正常,但我不喜欢这for部分.有没有办法在功能上写它?我试过了
if (Array.isArray(x))
yield *x.map(flat)
Run Code Online (Sandbox Code Playgroud)
这没用.
有没有办法在没有for循环的情况下编写上述函数?
考虑这个例子:
const samples = ["foo", "bar"];
const excludeFoos = function(item) {
return item !== "foo";
}
const foos = samples.filter(excludeFoos);Run Code Online (Sandbox Code Playgroud)
如何传递其他参数excludeFoos?
例如:
const samples = ["foo", "bar"];
const exclude = function(item, str) {
return item !== str;
}
// obviously won't work but you get the point
const foos = samples.filter(exclude("foo"));
console.log(foos); // ["bar"]Run Code Online (Sandbox Code Playgroud)
这似乎完全自然的,我认为发电机,其功能非常像数组,应该支持非常基本的列表操作,如map(),filter()和reduce()。我错过了什么吗?
我为map它编写了代码,看起来很简单,但是将所有函数嵌入所有生成器中会更好:
let fancyGen = g => {
let rv = function*() {
for (let x of g)
yield x;
}
rv.map = function*(p) {
for (let x of g)
yield p(x);
}
return rv;
}
Run Code Online (Sandbox Code Playgroud)
我是生成器的新手,因此欢迎对代码提出任何意见。特别是,这是编写“身份生成器”的最佳方式吗?
ecmascript-6 ×3
generator ×2
javascript ×2
fold ×1
haskell ×1
infinite ×1
iterator ×1
list ×1
map-function ×1
yield ×1