我真的不知道如何描述这个问题,跟函数式编程有关,求助

2014-04-19 09:33:31 +08:00
 notcome
我打算撸一个 PEG based Markdown Parser,练习一下。
然后我想写这么一个东西,注意 var = BIContent 一行:

function BIGen (token) {
var BIContent = R['/']([token, R['s']([Char, BIContent])]);
return R['s']([token, Char, BIContent]);
}

R['s'] 的参数为一个函数数组,返回一个函数,然后 R['/'] 的参数也是一个函数数组,返回一个函数。我现在希望实现一个递归,但是先求参数值的原因,所以……卡住了。

怎么办?

(我好像记得 SICP 中有有关内容,马上看看去)
4973 次点击
所在节点    Node.js
14 条回复
rannnn
2014-04-19 12:17:21 +08:00
没懂
mikawudi
2014-04-19 12:43:50 +08:00
参数先被求值,是指应用序和正则序的问题么?
jakwings
2014-04-19 13:22:38 +08:00
那个 BIContent 的定义简直是乱来。从纯逻辑上判断是根本不可能存在的。去掉那些杂碎后就好像在说:

> y = y;
< ReferenceError: y is not defined

简直无语。当然,用 var x = x; 是不会有错误提示的,因为有语法糖,相当于 var x = undefined; x = x;
jakwings
2014-04-19 13:27:33 +08:00
@jakwings Javascript 里面没有 C 语言那样的指针,除非你把 BIContent 赋到某个对象上,参数传的那个对象,还可以临时生成一个函数放上去,否则就别想无中生有了。
notcome
2014-04-19 15:38:33 +08:00
@mikawudi 是的,我希望生成一个函数调用自身
notcome
2014-04-19 16:05:06 +08:00
似乎想到一个好的办法

var self = {value: 'self'};
var failed = {value: 'failed'};

function prioritized_choose (choices) {
function this_expr (input, index) {
var result = failed;
for (var i = 0; i < choices.length; i ++) {
var test;
if (choices[i] == self)
test = this_expr(input, index);
else
test = choices[i](input, index);
if (test != failed) {
result = test;
break;
}
}
return result;
}
}

嗯, 还没测试, 有语法错误就逗比了……
但问题是需要调用这个 prioritized_choose(choices) 的是 choices 里的一个 function, 所以这个方法对我来说毫无价值, 呜呜. 求大神支援.
notcome
2014-04-19 16:09:00 +08:00
哦对可以新建一个对象:
var func_obj = {};
func_obj.func = xxxx(xxxx, func_obj);
func_obj.func(xxxx);

感觉好不优美……
xgod
2014-04-19 19:15:02 +08:00
function BIGen (token) {
var BIContent = R['/']([token, R['s']([Char, BIContent])]);
return R['s']([token, Char, BIContent]);
}

function series (first, second) {
return function (input, index) {
var result = first(input, index);
if (result) return result;
result = second(input, index);
return {output: result.output, index: result.index};
}
}

------------
真心不明白你想描述的问题是什么。你想返回一个闭包,然后在闭包函数里面引用闭包函数本身?
是这意思?
function series (first, second) {
var noname= function (input, index) {
var result = first(input, index);
if (result) return result;
result = noname(input, index);
return {output: result.output, index: result.index};
}
return noname;
}
xgod
2014-04-19 19:18:23 +08:00
如果没有明确的思路,不建义把代码写得这么绕,估计你想要的是一种类似延时执行的代码绑定操作。
如果是解析个语法解析器,写一个状态机模式,想好状态变化,写出来的性能与可读性也不会差。
jakwings
2014-04-19 19:44:44 +08:00
假如你的想法就是 7 楼那样的话,下面的实现够了:
https://gist.github.com/anonymous/a9aac2e6f96b53f1f1ac
Golevka
2014-04-20 01:49:50 +08:00
我感觉只要按照传统的stream的方法做就行了。你之所以会感觉难受是因为stream函数的类型是没办法直接写出来的
bolasblack
2014-04-22 06:56:37 +08:00
@notcome 实话说那段代码没看懂,不过如果只是要函数自己要调用自己的话,其实是可以使用 arguments.callee 这个东西的
easing
2014-04-22 12:47:42 +08:00
你要做的貌似是一个简化版的parser combinator, 但你这composite函数的方式不太对。Parser和做parse的函数应该分开构建,你用一个高阶函数做参数本身来定义这个高阶。。。
notcome
2014-04-22 16:36:44 +08:00
@easing 虽然不太懂您说的分开是指什么……但是没关系我照着 parser combinator 搜就可以了,学习中,谢谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/109170

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX