首先,我刚接触 TeX,只用它来处理数学表达式。在我看来,最显著的特点是 TeX 不尊重空格。
在 lambda 演算中,应用用并列表示。在基于 lambda 演算的编程语言(ML、Haskell)中,名称可能有几个字母长,因此,为了在应用中分隔名称,名称之间会放置一个空格。我想使用这些编程语言标准库中的函数名称,因此我不能放弃多字母名称。目前我在应用中使用“\”,但对我来说这似乎有点老套,而且会使代码混乱。最好的方法是什么?示例:您可以采用任何函数代码,例如
$foldr\ f\ z\ (x:xs) = f\ x\ (foldr\ f\ z\ xs)$
。顺便问一下,在 lambda 演算中,在“operatorname”中包含多字母名称是否正常?
答案1
这semantic
包在这里会很有用。除其他功能外,semantic
它还提供了保留字功能,允许您执行以下操作:
% Preamble:
\usepackage{semantic}
\reservestyle{\concretesyntax}{\mathtt}
\concretesyntax{let[let\;],in[\;in\;]}
% Later:
$\<let> x = 5 \<in> x$
生成此图像:
您可以用相同的方式定义foldr
、等(可能交换为其他内容)。f
\mathtt
除此之外,semantic
还提供连字符,可以修复:
和的间距.
。(两者之后都应该有空格,但之前不应该有空格。)
% Preamble:
\mathlig{:}{\!:}
\mathlig{.}{.\:}
% Later:
\lambda x: nat. x + 1
生成此图像:
注意:这些风格试图模仿 John Mitchell 的教科书中的风格编程语言基础。(奇怪的是,我的这本书的纸质副本中的格式与可在线下载的章节不同,所以请记住这一点。)在我看来,我上面的方法在重现他的格式方面比 egreg 的答案做得更好,后者破坏了周围的间距:
并删除了变量名上的斜体。
答案2
目前还不太清楚哪些符号后面应该跟空格,哪些符号后面不应该跟空格。
就像是
\newcommand{\lname}[1]{\mathop{\kern0pt\mathit{#1}}}
和
$\lname{foldr}\lname{f}\lname{z}(x:xs) =
\lname{f}x(\lname{foldr}\lname{f}\lname{z}xs)$
可能会产生良好的结果。换句话说,将您想要间隔的每个符号作为 \lname 的参数。人们可能会为其选择一个不同的名称:\?
例如。很难想象如何在没有明确标记的情况下自动呈现此类公式。
在标准 LaTeX 中可以获得与 Andrew Stacey 类似的效果:在序言中
\newenvironment{lambdac}
{\catcode` =12 \setupspace
\makeordinary{:}% to make the colon an ordinary symbol
%%% possible other \makeordinary declarations
$\mathgroup0 }
{$}
{\catcode` =\active\gdef\setupspace{\def {\;}}}
\makeatletter
\newcommand{\makeordinary}[1]{\@tempcnta=\mathcode`#1
\@tempcntb=\@tempcnta
\divide\@tempcntb by "1000
\multiply\@tempcntb by "1000
\advance\@tempcnta by -\@tempcntb
\mathcode`#1=\@tempcnta}
\makeatother
在文档中可以使用
\begin{lambdac}
foldr f z (x:xs)=f x (foldr f z xs)
\end{lambdac}
只应在输出中必须出现的位置放置空格。
注意:空间具有数学码"8000
,但是当空间的类别代码不同于 11 或 12 时,将忽略此数学码。活动空间的间接定义避免了可能干扰命令的全局定义\verb
。
注意:\makeordinary
宏从数学码中去掉第一个十六进制数字。
结果:
答案3
我自己也曾为同样的问题而苦苦挣扎,最后得到了两个可能的解决方案;第一个基本上是 egreg 的解决方案(尽管你可以直接将函数变成宏,即\foldr
)。另一个是制作数学模式服从空间,但这也有其自身的问题。
最后,你基本上不会用其中任何一种方式节省任何输入时间。
稍微扩展一下,我所做的是定义宏(这些是纯格式,乳胶格式看起来不同):
\def\defun#1{\mathop{\hbox{\it#1}}} % define functions as math operators,
% so they get the spacing (note: not a "full" space, but a '\,'-space.)
\def\foldl{\defun{foldl}}
\def\foldr{\defun{foldr}}
\def\map{\defun{map}}
\def\filter{\defun{filter}}
\def\head{\defun{head}}
% etc. Silly, I know.
\def\f{\mathop f} % I don't want to remove the math italic kerning from 'f',
% because it has some additional space
$$ \foldr \f z (x:xs) = \f x (\foldr \f z\, xs) $$
% Note: I didn't want to remove the spacing of ':', and also, I used
% a manual spacing ('\,') to separate parameters.
\bye
输出如下所示:
虽然有点繁琐,但我认为看起来不错。
请注意,与此处不同,惯例是在开括号前留一个空格。我在此谦虚地挑战该惯例。:)