切割运行时计算的值



切割是一种非常有用的组合器,可最大程度地减少代码重复。假设我想对丰富,完美,不足的数字进行分类:

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不编译,因为"不能将切割应用于运行时计算的值"。

如果我不能使用裂解,那么我必须从本质上做:

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

la脚更长,如果钥匙串长期更长,并且会变得非常丑陋。另外,重要的是,如果在运行时生成密钥数组,则不可能在没有切割的情况下进行操作。

对于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 ]
}

Gross。

是否有组合替换运行时计算值的cleave?我可以在运行时允许计算时最大程度地减少丑陋的重复吗?

cleave可能不是正确的答案。当因子说无法将某些内容应用于运行时计算的值时,这意味着可以更好地写出一些东西。我想在这里您想用直方图替换cleave

IN: scratchpad 100 [ { "abundant" "deficient" "perfect" } random ] replicate 
    histogram
--- Data stack:
H{ { "deficient" 33 } { "perfect" 30 } { "abundant" 37 } }

最新更新