我将以简单的英语解释我的问题,然后展示我在J的尝试。
对1和0的列表的1的索引求和,看看它们是否等于另一个数字。 例如给1 0 1 1 0 索引是0,2和3,它们的总和是5.所以我可以测试它是否可以判断另一个数字(在这种情况下,显然只有5)。
这是我的J:
indexsumtest =: =+/I.
v =: 1 0 1 1 0
5 indexsumtest v
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
什么?这里我假设indexsumtest是一个二元动词,也许我需要明确地输入x和y?
indexsumtest =: x =+/I. y
5 indexsumtest v
|value error: x
| 5 indexsumtest v
不。这让事情变得更糟。
所以我从头开始:
I. v
0 2 3
正确!
+/I. v
5
再次纠正。
5 =+/I. v
1
1表示真实。所以我做对了。
为什么我不能将这三个操作压缩成单个动词?
答案 0 :(得分:3)
这是一个偶尔咬人的结果,因为
5 =+/I. v
实际上有I.作用于v,然后结果被+ /作用,然后使用=比较对照结果进行测试。所以当我们定义
时 indexsumtest =: =+/I.
我们得到了
5 indexsumtest v
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
因为indexsumtest已被定义为默认动词,它将其参数作为MPelletier建议的fork处理。换句话说,你实际上没有= + / I。代替indexsumtest你得到(= + / I。)这是一个3动词叉,其中第一个和第三个动词同时接受两个参数,每个动词的结果被发送到中心的+ /。
MPelletier还建议做出你想要的隐性形式
[ = [: +/ [: I. ]
如果您将定义更改为13
,它将起作用并且实际上是由J创建的indexsumtest =: 13 : 'x =+/I. y'
indexsumtest
[ = [: +/ [: I. ]
是的,如果您使用13:conj来定义,那么J实际上会为您进行大多数默认转换。很酷,嗯?唯一的问题是它不会在这个自动生成中使用钩子,这可以简化代码。一个钩子是一个双动词组合,它在右边的参数上有正确的动词作用,结果被用作左动词的右参数,它使用二元情形中的左参数(或monadic情形中的原始右参数)
当x和y是左右参数时,u和v是第一个和第二个动词,那么
x ( u v) y
变为x u (v y)
或以monadic case
( u v) y
变为y u (v y)
如果你还在我身边(对你有好处!)这意味着如果我们将你设置为=和v到+ / @我,我们可以使用一个钩子来简化默认。 (@是一个连接+ /和I的连接,并使它们作为一个动词起作用)。最后
indexsumtacit =: = +/@I.
5 indexsumtacit v
1
正如J开始时的心态,当你理解它所遵循的规则然后开始让它们进行你的出价时,它真的很整洁。希望这会有所帮助。
答案 1 :(得分:1)
考虑经典的均值函数:
mean =: +/%#
mean i.6
像这样的3部分声明以这种方式运作:
#
针对y
+/
针对y
%
分别针对+/
和#
在各自位置的结果执行原则与你的二元函数相同:
I.
针对x
和y
=
针对x
和y
+/
是针对各自所在地=
和I.
的结果执行的。所以,做
indexsumtest =: =+/I.
5 indexsumtest 1 0 1 1 0
相当于
(5 = 1 0 1 1 0) +/ (5 I. 1 0 1 1 0)
远非你想要的。
简单的技巧是明确定义二元函数:
indexsumtest =: 4 : 'x =+/I. y'
J的默认定义也表明了这一点:
[ = [: +/ [: I. ]
根据我的口味,这有点重。
答案 2 :(得分:0)
关于J如何解析表达式。当J看到一个动词时,它隐含地在它周围添加一个括号。所以5 indexsumtest v
是5 (=+/I.) v
;而5 =+/I. v
实际上是5 =+/ (I. v)
。这两个与上面的答案不同。
我发现通过阅读Appendix 1 of Learning J来了解J如何评估表达式是非常有帮助的。对于任何J教程,这应该是整章而不是附录。