:@$:)@.(3 :'?2')"0 i. f-6ren">
gpt4 book ai didi

J语言。我想要以函数形式表达结果

转载 作者:行者123 更新时间:2023-12-01 11:23:43 27 4
gpt4 key购买 nike

(+/%#)0:`(>:@$:)@.(3 :'?2')"0 i.10000

如我所想的那样工作。答案倾向于1。现在我想用

f =: (+/%#)0:`(>:@$:)@.(3 :'?2')"0 i.
f 10000

不起作用。

最佳答案

隐式与显式组合

通过 J 中的并置将几个动词串在一起并不会创建管道,它会创建一个“verb train”,它具有不同的语义。

名词短语:

foo bar bar buz 10000

不同于动词短语:

f =: foo bar baz buz
f 10000

如果你想要动词管道,你必须使用某种形式的 explicit composition (即表示,而不是暗示)。

最常见的是,管道由一元动词组成(将一个输入转换为一个输出,成为下一个动词的输入),因此我们使用@:(或@,但使用它需要更多地注意细节),因此与原始名词短语的口头等价物是:

f =: foo @: bar @: baz @: buz
f 10000

组合和匿名递归

鉴于您的情况,我们可能会天真地写成:

(+/%#) @: (0:`(>:@$:)@.(3 :'?2')"0) @: i.

注意将中间动词 (0:`(>:@$:)@.(3 :'?2')"0) 括在括号中,因为我们想应用它动词,并且只有那个动词,排名为零 ("0),特别是将平均值 (+/% #) 应用于整个结果,而不是应用于每个个体结果。

但如果我们这样做并运行它,我们很快就会遇到一个问题:无限递归

在原始名词短语中,动词 0:`(>:@$:)@.(3 :'?2')"0 单独存在,因此 $ :(匿名递归)在该动词中引用 0:`(>:@$:)@.(3 :'?2')"0 并且仅引用 0 :`(>:@$:)@.(3 :'?2')"0.

但是,一旦我们将三个动词的序列重新表述为一个管道(f,上面),那么 $: 就会嵌入到 f 中因此 指的是 f

意思是,在 f 的这个公式中,当 $: 在 1 上递归时,首先,i. 被应用到那个 1,导致 ,0,然后 ? 生成一个随机位,它有 50% 的机会是 1,然后 $: 递归, i. 应用于....

这是 J 中经常遇到的陷阱。有两种传统的解决方案。

隔离$:

您可以将您的代码分成更小的、命名的部分:

f          =:  mean @: converge @: i.
mean =: +/ % #
converge =: 0:`(>:@$:)@.(3 :'?2')"0

因为它隔离了 $:,所以确保它只引用 converge

同样,您可以将 $: 嵌入匿名显式上下文中,从本质上限制其权限:

f =:  (+/%#) @: (verb def '0:`(>:@$:)@.(3 :'?2')"0 y') @: i.

这就像在 $: 上戴上眼罩:现在它无法看到 verb def 之外的东西。一些默认的纯粹主义者可能会对这种方法犹豫不决,但有一点 the J interpreter itself employed this tactic当使用 f..

修复带有嵌入式 $: 的定义时

解决方案

鉴于您对 3 : '?2' 的使用,您似乎对匿名显式上下文很满意。如果是这种情况,那么也许值得全力以赴,将原始的、未改变的名词短语捕获为显式动词:

meanConverge =: verb define
(+/%#) 0:`(>:@$:)@.(3 :'?2')"0 i. y
)

但是,如果您更喜欢一个纯粹的默认解决方案,并且想在其他方向上全力以赴,我们甚至可以消除 3 : '?2' 显式代码:

f          =:  mean @: converge @: i.
mean =: +/ % #
converge =: 0:`(>:@$:)@.(?@2:)"0

当然,还有一些方法可以重写动词来完全避免递归,但这可能会违背练习的目的。

关于J语言。我想要以函数形式表达结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39495059/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com