Странная ошибка длины при определении соединения в J - PullRequest
3 голосов
/ 07 августа 2011

Я играю с наречиями и соединениями в J, и натолкнулся на странную проблему.Я определил простое наречие под названием persistence, которое можно использовать для просмотра последовательности чисел, сгенерированных при вычислении цифрового продукта или цифровой суммы числа.

S =: 1 : 'u/@:("."0)@":^:a:"0'

+ S 234 дает нам 234 9.Затем я использовал это, чтобы создать другое наречие, которое вычисляет постоянство числа.

P =: 1 : '<:@#@(u S)"0'

+ P 234 дает нам 1.Теперь представьте, что мы хотим найти все числа ниже 30 с аддитивной постоянностью 2, а затем просмотреть список, сгенерированный S для каждого числа, например,

+ S I. 2 = + P i.30

. Это создает следующий список:

19 10 1
28 10 1
29 11 2

Пока все хорошо.Теперь я хотел взять это и превратить в соединение, в левой части которого содержится глагол для сохранения, а в правой - число, используемое для ограничения списка.(2 в вышеприведенном примере.) Вот мое определение этого соединения:

Q =: 2 : 'u S I. n = u P'

Если я введу выражение + Q 2 в консоль J, я получу следующее:

+/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0

Это совершенно правильно, и если я запускаю полное выражение с аргументом, таким как i.30, оно работает нормально:

+/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0 i.30

Однако, когда я ввожу выражение + Q 2 i.30 вJ консоль, я получаю «ошибку длины».Зачем?!Разве + Q 2 точно не эквивалентно +/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0?

Я в полном замешательстве.Что мне не хватает?Я играл с рангом как внутри определения соединения, так и вне его.Я просто не понимаю.

1 Ответ

3 голосов
/ 14 августа 2011

+ Q 2 в точности соответствует предоставленному вами выражению, но при использовании его в выражении оно выглядит так, как если бы оно было в скобках.

   +/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0 i.30
19 10 1
28 10 1
29 11 2
   (+/@:("."0)@":^:a:"0 I. 2 = <:@#@(+/@:("."0)@":^:a:"0)"0) i.30
|length error

В общем f g h y! = (f g h) y. В последнем f g h определяет поезд . Например:

   avg=: +/ % #
   +/ % # 1 2 3
0.333333
   (+/ % #) 1 2 3
2
   avg 1 2 3
2

Вы можете исправить свое соединение, добавив к нему ссылку на y следующим образом:

   Q=: 2 : 'u S I. n = u P y'
   + Q 2 i.30
19 10 1
28 10 1
29 11 2
...