Как определить / @ -подобный оператор - PullRequest
7 голосов
/ 18 апреля 2011

Я хотел бы определить новый оператор в форме x /==> y, где оператор /==> рассматривается как, например, оператор /@ для Map и переводится в MyFunction[x, y].Есть один важный аспект: я хочу, чтобы результирующий оператор вел себя во внешнем интерфейсе так же, как любой двухбитный оператор, то есть два символа (Divide и DoubleLongRightArrow) должны быть соединены вместе, окраска синтаксиса не должнапоявляются, и они должны быть выбраны вместе при нажатии, поэтому приоритет должен быть установлен.Кроме того, я бы предпочел не использовать пакет Notation`.В результате я хотел бы видеть что-то вроде этого:

In[11]:= FullForm[x/\[DoubleLongRightArrow]y]

Out[11]//FullForm= MyFunction[x,y]

У кого-нибудь есть идеи, как этого добиться?

Ответы [ 2 ]

6 голосов
/ 18 апреля 2011

Пакет для обозначений , возможно, наиболее близок к выполнению подобных вещей, но согласно ответу на мой собственный вопрос аналогичного характера , то, что вы хотите, к сожалению, не практично ,

Не позволяйте этому помешать вам, однако, поскольку вы, вероятно, узнаете что-то новое в процессе. Пакет обозначений и функции, лежащие в его основе, далеко не бесполезны.

Вы также можете найти ответы на на этот вопрос информативно.


Существует ряд функций, которые полезны для ручной реализации изменений синтаксиса. Вместо того, чтобы пытаться написать собственный файл справки для них, я направлю вас на официальные страницы с этими функциями. После их прочтения, пожалуйста, задавайте любые конкретные вопросы, которые у вас есть, или для помощи в реализации конкретных идей. Я или другие здесь должны быть в состоянии ответить на ваш вопрос, показать, как что-то сделать, или объяснить, почему это невозможно сделать.

Их больше, и я постараюсь расширить этот список позже. ( другие могут редактировать это сообщение )

2 голосов
/ 19 апреля 2011

Благодаря ссылкам Mr.Wizard, я нашел единственный пример в документации о том, как разобрать новых операторов (пример gplus в низкоуровневом вводе ). Согласно этому примеру, вот моя версия для нового оператора PerArrow. Пожалуйста, комментируйте / критикуйте код ниже:

In[1]:= PerArrow /: MakeBoxes[PerArrow[x_, y_], StandardForm] := 
  RowBox[{MakeBoxes[x, StandardForm], 
    RowBox[{AdjustmentBox["/", BoxMargins -> -.2], 
      AdjustmentBox["\[DoubleLongRightArrow]", BoxMargins -> -.1]}], 
    MakeBoxes[y, StandardForm]}];

MakeExpression[
   RowBox[{x_, "/", RowBox[{"\[DoubleLongRightArrow]", y_}]}], 
   StandardForm] := 
  MakeExpression[RowBox[{"PerArrow", "[", x, ",", y, "]"}], 
   StandardForm];

In[3]:= PerArrow[x, y]

Out[3]= x /\[DoubleLongRightArrow] y

In[4]:= x /\[DoubleLongRightArrow]y

Out[4]= x /\[DoubleLongRightArrow] y

In[5]:= FullForm[x /\[DoubleLongRightArrow]y]

Out[5]//FullForm= \!\(\*
TagBox[
StyleBox[
RowBox[{"PerArrow", "[", 
RowBox[{"x", ",", "y"}], "]"}],
ShowSpecialCharacters->False,
ShowStringCharacters->True,
NumberMarks->True],
FullForm]\)

Для ясности, вот скриншот: new operator

Поскольку оператор не полностью интегрирован, дальнейшие проблемы:

  • оператор выбирается странно при нажатии (DoubleLongRightArrow с y вместо /).
  • соответственно, для синтаксического анализа требуется, чтобы DoubleLongRightArrow был RowBox -ed с y , в противном случае выдается синтаксическая ошибка
  • окраска синтаксиса (при In[4] и In[5])
  • печатается странно, если вводится напрямую (обратите внимание на большие пробелы в In[4] и In[5])

Теперь я могу жить с этим, хотя было бы неплохо иметь некоторые средства, чтобы сгладить все мелкие проблемы. Я предполагаю, что все это сводится к некоторому даже низкоуровневому синтаксическому обработчику, который не делает сейчас, как группировать новый оператор. Любая идея о том, как справиться с этим? Я понимаю, что у Cell есть множество опций, которые могут пригодиться (например, CellEvaluationFunction, ShowAutoStyles и InputAutoReplacements), хотя я снова здесь не понимаю.

...