如何强制对单子动词进行分组?

How to force grouping of monadic verbs?

脑子里想出了一个不正确的J动词,会求字符串中多余字母的比例。我从一堆没有定义优先级的动词开始,然后尝试向内分组:

   c=. 'cool' NB. The test data string, 1/4 is redundant.
   box =. 5!:2 NB. The verb to show the structure of another verb in a box.
   p=.%#~.%# NB. First attempt. Meant to read "inverse of (tally of unique divided by tally)".
   box < 'p'
┌─┬─┬────────┐
│%│#│┌──┬─┬─┐│
│ │ ││~.│%│#││
│ │ │└──┴─┴─┘│
└─┴─┴────────┘
   p2=.%(#~.%#) NB. The first tally is meant to be in there with the nub sieve, so paren everything after the inverse monad.
   box < 'p2'
┌─┬────────────┐
│%│┌─┬────────┐│
│ ││#│┌──┬─┬─┐││
│ ││ ││~.│%│#│││
│ ││ │└──┴─┴─┘││
│ │└─┴────────┘│
└─┴────────────┘
   p3=. %((#~.)%#) NB. The first tally is still not grouped with the nub sieve, so paren the two together directly. 
   box < 'p3'
┌─┬────────────┐
│%│┌──────┬─┬─┐│
│ ││┌─┬──┐│%│#││
│ │││#│~.││ │ ││
│ ││└─┴──┘│ │ ││
│ │└──────┴─┴─┘│
└─┴────────────┘
   p3 c  NB. Looks about right, so test it!
|length error: p3
|       p3 c
   (#~.)c  NB. Unexpected error, but I guessed as to what part had the problem.
|length error
|       (#~.)c

我的问题是,为什么我的分组方法会因长度错误而失败,我应该如何分组才能获得预期的效果? (我认为这与将它变成一个钩子而不是分组有关,或者它只是没有意识到它需要使用 monad 形式,但如果是这样,我不知道如何验证或绕过它。)

Fork and compose.

(# ~.) 是一个 hook。这可能是您意想不到的。 (# ~.) 'cool'~. 应用到 'cool' 给你 'col'。但是因为它是一个 monadic 钩子,所以它会尝试 'cool' # 'col',这不是您想要的,并且会给出长度错误。

要获得 0.25 作为字符串中冗余字符的比率,请不要使用倒数 (%)。您只需从 1 中减去唯一字符的比率。使用叉子这非常简单:

   (1 - #&~. % #) 'cool'
0.25
   p9 =. 1 - #&~. % #
   box < 'p9'
┌─┬─┬──────────────┐
│1│-│┌────────┬─┬─┐│
│ │ ││┌─┬─┬──┐│%│#││
│ │ │││#│&│~.││ │ ││
│ │ ││└─┴─┴──┘│ │ ││
│ │ │└────────┴─┴─┘│
└─┴─┴──────────────┘

Compose (&) 确保您将 nub (~.) 计数 (#) 在一起,以便 fork 将其作为单个动词抓住。叉子是一系列三个动词,应用第一个和第三个动词,然后将中间动词应用到结果。所以 #&~. % # 是分叉,其中 #&~. 应用于字符串,结果是 3# 被应用,导致 4。然后 % 应用于这些结果,如 3 % 4,给你 0.75。那是我们独特字符的比例。

1 -只是让我们得到0.25而不是0.75% 0.751 % 0.75 相同,即 1.33333.