一千萬個為什麽

搜索

優先級低的前綴運算符

問題很簡單,但我會詳細說明那些對這個想法感興趣的人的背景: 如何定義具有指定優先級值的新運算符?

背景 Mathematica was design to facilitate functional programming. I definitely find it easy to write code continuously: the output of a function becomes immediately the input of the next function. One thing I really miss though is a low-precedence prefix operator that applies to all things following it (up to e.g. CompoundExpression (;)). Consider the following example: [email protected]@[email protected]# & /@ Partition[[email protected], 100]//Flatten//ListPlot

它將數據集分區為多個子部分,線程函數分配給每個子部分,然後繪制連接的數據集。我編寫了很多這樣的代碼,因為我發現它很容易從內到外編寫,從參數到頭部(從右到左)。問題是上述問題的擴展可能直觀地表現出來並不是這樣的: [email protected]@ [email protected]@[email protected]# & /@ Partition[[email protected], 100]

運算符優先級導致 ListPlot @ Flatten 應用於分區列表的每個子部分而不是整個列表。現在,因為我連續地從參數到包裝函數構建我的計算,我想使用前綴運算符。我擔心的是:

可以使用匹配修復表單,如 f @(...)或 f [...] 來包裝 Map ,雖然它需要匹配括號,當使用前綴表示法應用多個這樣的函數時,它可以是PITA。 使用postfix //都會打破我從右到左書寫的認知過程,並且(更重要的是)打破了head-precedes-argument的原則,這在 Mathematica (以及$ \ lambda $ -calculus)。 操作員必須是自由符號。應避免修改內置的 @ 運算符! 此外,它必須足夠簡單才能有效使用。 Postfix apply //是2次擊鍵,而例如$ \ oplus $需要4次( esc c + < kbd> esc ),使其比擊中 end / /更糟糕。

那麽,如何定義一個新的運算符,例如 \ 具有低優先級(可能是70),因此: ListPlot \ Flatten \ [email protected]@[email protected]# & /@ Partition[[email protected], 100]

等於這個: ListPlot[Flatten[[email protected]@[email protected]# & /@ Partition[[email protected], 100]]]

坦率地說,我開始想知道為什麽這個運算符在 Mathematica 中根本不存在,盡管WRI總是強調函數式編程作為該語言的本機風格。

我知道我可以將 Log 或 N 作為一個整體應用於分區列表。我只是在這裏使用它們來展示我的情況。

最佳答案

As explained by Michael Pilat you cannot create your own compound operators* with custom precedence. (You could conceivably write your own parser as Leonid has worked on, or attempt to coerce the Box form with CellEvaluationFunction.) 但是,您可以使用具有所需優先級的現有運算符。查看表 冒號似乎是一個好的選擇。使用 Esc : Esc 輸入運算符。例: SetAttributes[Colon, HoldAll] Colon[f_, x] := Composition[f][[email protected]]

ListPlot [Colon] Flatten [Colon] [email protected]@[email protected]# & /@ Partition[[email protected], 100]

出現,並產生:

由於原始冒號已經用於 Pattern ,這可能會令人困惑。但是,如果您願意編輯 UnicodeFontMapping.tr 文件,則可以指定您喜歡的任何符號。在這裏,我將 \ [Colon] 映射到 Klingon A:

這是通過在 UnicodeFontMapping.tr 中更改以 0x2236 開頭的行來完成的。

  • Rojo演示了可以創建二維復合運算符,這意味著使用 SubscriptBox , SuperscriptBox , OverscriptBox 等。見:

是否可以定義自定義復合賦值運算符,例如⊕=類似於內置函數+ =,* =等?

轉載註明原文: 優先級低的前綴運算符