2016-06-21 72 views
3

Cleave是一个非常有用的组合器,用于最小化代码重复。假设我要分类Abundant, Perfect, Deficient numbers解除运行时计算值?

USING: arrays assocs combinators formatting io kernel math 
math.order math.primes.factors math.ranges sequences ; 
IN: adp 

CONSTANT: ADP { "deficient" "perfect" "abundant" } 

: proper-divisors (n -- seq) 
    dup zero? [ drop { } ] [ divisors dup length 1 - head ] if ; 

: adp-classify (n -- a/d/p) 
    dup proper-divisors sum <=> 
    { +lt+ +eq+ +gt+ } ADP zip 
    H{ } assoc-clone-like at ; 

: range>adp-classes (n -- seq) 
    1 swap 1 <range> [ adp-classify ] map 
    ADP dup 
    [ 
    [ 
     [ = ]  curry 
     [ count ] curry 
    ] map 
    cleave 3array 
    ] dip 
    swap zip H{ } assoc-clone-like ; 

: print-adp-stats (seq --) 
    ADP [ 
    [ dup [ swap at ] dip swap "%s: %s" sprintf ] curry 
    ] map cleave 
    [ print ] [email protected] ; 

range>adp-classes不编译,因为“不能适用于切割运行时间计算值”。

如果我不能使用切割,然后我基本上做到:

[ [ [ "deficient" = ] count ] 
    [ [ "abundant" = ] count ] 
    [ [ "perfect" = ] count ] 
    tri 
] dip 

这是瘸又长,会得到真正的丑陋和更长久的关键字符串数组更长。另外,重要的是,如果在运行时生成密钥数组,那么不分割就不可能。

同样为print-adp-stats:无cleave我就必须有这个文字在我的源躺在身边:

{ 
    [ "deficient" dup [ swap at ] dip swap "%s: %s" sprintf ] 
    [ "perfect" dup [ swap at ] dip swap "%s: %s" sprintf ] 
    [ "abundant" dup [ swap at ] dip swap "%s: %s" sprintf ] 
} 

毛。

是否有一个组合器替换cleave的运行时间计算值?我是否可以通过其他方式将丑陋重复最小化,同时仍允许在运行时进行计算?

回答

2

cleave可能不是正确的答案。当Factor表示不能将SOMETHING应用于运行时计算值时,通常意味着可以写得更好。我想在这里你想用直方图替换cleave

IN: scratchpad 100 [ { "abundant" "deficient" "perfect" } random ] replicate 
    histogram 

--- Data stack: 
H{ { "deficient" 33 } { "perfect" 30 } { "abundant" 37 } }