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 ] tri@ ;
range>adp-classes
无法编译,因为&#34;无法将cleave应用于运行时计算值&#34;。
如果我不能使用cleave,那么我必须基本上做:
[ [ [ "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
的运行时计算值?我可以通过其他方式最小化丑陋的重复,同时仍允许在运行时进行计算吗?
答案 0 :(得分:2)
cleave
可能不是正确答案。当因子说无法将SOMETHING应用于运行时计算值时,通常意味着可以更好地编写某些内容。我想在这里你要用直方图替换cleave
:
IN: scratchpad 100 [ { "abundant" "deficient" "perfect" } random ] replicate
histogram
--- Data stack:
H{ { "deficient" 33 } { "perfect" 30 } { "abundant" 37 } }