论坛首页 Java企业应用论坛

ajoo的jaskell和jparsec

浏览 14930 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-02-07  
age0提出了一个本身也许就用OO实现半斤八两甚至可能更方便的问题,我也说了,这种event-handler的东西并不是fp的强项,
fp的倾向在于组合,在于声明式。比如你用写了几个不同的模块,可以在配置文件里面用jaskell把他们灵活地组合起来。
也可能用这个来写单元测试和集成测试的脚本。

另外,看来大家对函数式还是比较缺乏了解的,我在编程版贴了一个关于各个语言quicksort的代码比较。robbin看合适放在哪里就挪吧,谢了!
0 请登录后投票
   发表时间:2005-02-12  
改进了语法。根据大家的意见,增加了java风格的用括号和逗号分隔参数的语法。也改进了let-in的语法,在不需要返回值的时候,可以象java一样只写表达式本身。

下面这个重新写了的weave_trace函数尽量使用大家喜闻乐见的语法,用来向一个actions的集合里面的某一个action织入trace。
它假设这些action都是一个参数的函数。如果有更多的参数,只需传递另外的weaver函数。这在OO里也是如此,而且只会更繁琐。


weave_trace(acts, "折扣2 = 3%", ac_trace_action, ac_trace_action, weaver1); 
where
  weave_trace(acts, key, pre, post, weaver); = 
    acts.setAction(key,
      weaver(pre, post, acts.getAction(key););
    );;
  weaver1(pre, post, f, x); = let
      pre;
      r = f(x);;
      post;
    in r;
;


用点更加fp的语法和Fp'er津津乐道的point-free style的话,会省掉很多括号,代码转换成为这样。

weave_trace acts "折扣2 = 3%" ac_trace_action ac_trace_action weaver1
where
  weave_trace acts key pre post weaver = 
    transform acts key $ weaver pre post;
  transform  acts key f =
    acts.setAction key $ f $ acts.getAction key;
  weaver1 pre post f x = let
      pre;
      r = f x;
      post;
    in r;
;

其中$符号用来改变优先级,相当于括号的一个变种。
此外,也可以在两者之间搞点折中,以得到更符合个人审美的代码。

这里面不同的参数个数对应不同的weaver,但是其它的如weave_trace, transform这些函数都是不变的。
虽然语法仍然不能指望让业务人员掌握,但是我想也很难找到语法更加简单的语言了吧? 毕竟是aop呀。

我前面说在这种需求面前fp不占优势,不过现在看来,还是有优势的。
age0给的那个代码,其实核心的关于+=的那个delegate只不过是用了语言内部定义的一个特殊设施而已。如果用java,那么就还是需要写成库。而写成的库我相信,无论如何会比我上面给的代码复杂。

而直接对应age0给出的那段代码,jaskell的版本也一样简洁:
let 
  facts = new_fact
    .New("价格", "100");
    .New("数量", "2");
    .New("货物名称", "猪");;
  acs = new_actions
    .New("折扣1 = 5%", "数量 > 100 or 货物名称='猪' ");;
    .New("折扣2 = 3%", "数量 > 10 and 数量 < 100");;
    .New("折扣3 = 0%", "数量 <= 10");;
    .New("折扣 = Max(折扣1, 折扣2, 折扣3);");;
    .New("总额 = 价格 * 数量 * (100% - 折扣);");;
  acs = weave_trace(acs, "折扣2 = 3%", ac_trace_action, ac_trace_action);;
  result = acs.OnAction(facts);;
  total = result.Get("总额");;
  discount = results.Get("折扣");; 
in
  "total is $total, discount is $discount"


注意,我没有用age0的current_ac,不是jaskell做不了类似的东西,而是我认为这样设计不好,耦合性较强,而且在声明性的代码中间插入过程式的trace这种东西,也总感觉不是那么回事。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics