答案1
另一种解决方案,具有简单的tabular
环境和uppunctlm
包,它使用直立标点符号和斜体数字以及字体lm
:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{uppunctlm}
\usepackage{amsmath}
\usepackage{array, caption, booktabs}
\captionsetup{font = footnotesize}
\newcommand{\sub}[1]{\/\textsubscript{#1}}
\begin{document}
\begin{figure}
\centering
\fbox{%
\itshape\footnotesize\renewcommand{\arraystretch}{1.25}\setlength{\tabcolsep} {4pt}
\begin{tabular}{r >{$}c<{$}l >{\upshape}l}
\addlinespace[2.5ex]
polytype & \to & context $ => $ monotype & \\
& \vert & monotype & \\[2ex]
monotype & \to & tyvar & Type variable \\
& \vert & monotype\sub{1} –${>} $ monotype\sub{2} & Function type \\
& \vert & [monotype] & List type \\
& \vert & (monotype\sub{1},\,…, monotype\sub{n}) \quad $ (n=0\text{ or }n\ge2) $ & Tuple type (incl.\ unit) \\
& \vert & tycon monotype\sub{1} … monotype\sub{n} \quad $ (n\ge0) $ & Constructed type \\[2ex]
context & \to & class\/\sub{1} tyvar\sub{1},\,…, class\sub{n} tyvar\sub{n} \\
\addlinespace[2.5ex]
\end{tabular}}%
\caption{Abstract syntax of Haskell: types}
\end{figure}
\end{document}
答案2
我不知道有哪个包有这么多的精妙之处。这是手工制作的版本。
\documentclass[a4paper]{article}
\usepackage{amsmath}
\usepackage{calc}
\newcommand{\mv}[1]{% metavariable
\mathit{#1}%
}
\newcommand{\sor}{% syntax or
\mathrel{\makebox[\widthof{$\to$}]{$|$}}%
}
\newcommand{\sTO}{\mathrel{\texttt{=>}}}
\newcommand{\sto}{\mathrel{\texttt{->}}}
\newcommand{\slp}{\mathopen{\texttt{(}}}
\newcommand{\srp}{\mathopen{\texttt{)}}}
\newcommand{\slb}{\mathopen{\texttt{[}}}
\newcommand{\srb}{\mathopen{\texttt{]}}}
\newcommand{\slc}{\mathpunct{\texttt{,}}}
\begin{document}
\begin{figure}
\centering
\footnotesize % adapt to your page size
\fbox{%
$\begin{aligned}
\mv{polytype} & \to \mv{context} \sTO \mv{monotype}
&& \\
& \sor \mv{monotype}
&& \\[2ex]
\mv{monotype} & \to \mv{tyvar}
&& \text{Type variable} \\
& \sor \mv{monotype}_1 \sto \mv{monotype}_2
&& \text{Function type} \\
& \sor \slb\mv{monotype}\srb
&& \text{List type} \\
& \sor \slp\mv{monotype}_1\slc\dots\slc\mv{monotype}_n\srp
\quad (n=0\text{ or }n\ge2)
&& \text{Tuple type (incl.\ unit)} \\
& \sor \mv{tycon}\,\mv{monotype}_1\dots\mv{monotype}_n
\quad (n\ge0)
&& \text{Constructed type} \\[2ex]
context & \to \slp\mv{class}_1\,\mv{tyvar}_1\slc\dots\slc\mv{class}_n\,\mv{tyvar}_n\srp
\end{aligned}$%
}
\caption{Abstract syntax of Haskell: types}
\end{figure}
\end{document}
您可以通过更多的工作来获得更好的语法。
\documentclass[a4paper]{article}
\usepackage{amsmath}
\usepackage{calc,booktabs,xparse,environ}
% syntax symbols
\newcommand{\STO}{&\to}
\newcommand{\SOR}{&\mathrel{\makebox[\widthof{$\to$}]{$|$}}%
}
\newcommand{\REM}[1]{&&\text{#1}}
% Haskell symbols
\newcommand{\mv}[1]{\mathit{#1}}% metavariable
\newcommand{\hTO}{\mathrel{\texttt{=>}}}
\newcommand{\hto}{\mathrel{\texttt{->}}}
\newcommand{\hlp}{\mathopen{\texttt{(}}}
\newcommand{\hrp}{\mathopen{\texttt{)}}}
\newcommand{\hlb}{\mathopen{\texttt{[}}}
\newcommand{\hrb}{\mathopen{\texttt{]}}}
\newcommand{\hlc}{\mathpunct{\texttt{,}}}
\ExplSyntaxOn
\NewEnviron{haskellsyntax}
{
\tl_replace_all:Nnn \BODY { \par } { }
$\begin{aligned}
\haskell_syntax:V \BODY
\end{aligned}$
}
\cs_new_protected:Nn \haskell_syntax:n
{
\seq_clear:N \l_haskell_syntax_output_seq
\seq_set_split:Nnn \l_haskell_syntax_body_seq { \\ } { #1 }
\seq_map_inline:Nn \l_haskell_syntax_body_seq
{
\seq_set_split:Nnn \l_haskell_syntax_row_seq { \SOR } { ##1 }
\seq_put_right:Nx \l_haskell_syntax_output_seq
{
\seq_use:Nn \l_haskell_syntax_row_seq { \haskell_syntax_break: }
\exp_not:N \\
}
}
\seq_use:Nn \l_haskell_syntax_output_seq { \addlinespace }
}
\cs_generate_variant:Nn \haskell_syntax:n { V }
\cs_new_protected:Nn \haskell_syntax_break: { \\ \SOR }
\ExplSyntaxOff
\begin{document}
\begin{figure}
\centering
\footnotesize % adapt to your page size
\fbox{%
\begin{haskellsyntax}
\mv{polytype} \STO \mv{context} \hTO \mv{monotype}
\SOR \mv{monotype}
\\
\mv{monotype} \STO \mv{tyvar}
\REM{Type variable}
\SOR \mv{monotype}_1 \hto \mv{monotype}_2
\REM{Function type}
\SOR \hlb\mv{monotype}\hrb
\REM{List type}
\SOR \hlp\mv{monotype}_1\hlc\dots\hlc\mv{monotype}_n\hrp
\quad (n=0\text{ or }n\ge2)
\REM{Tuple type (incl.\ unit)}
\SOR \mv{tycon}\,\mv{monotype}_1\dots\mv{monotype}_n
\quad (n\ge0)
\REM{Constructed type}
\\
context \STO \hlp\mv{class}_1\,\mv{tyvar}_1\hlc\dots\hlc\mv{class}_n\,\mv{tyvar}_n\hrp
\end{haskellsyntax}%
}
\caption{Abstract syntax of Haskell: types}
\end{figure}
\end{document}