Haskell 笔记 1

最近在学门新语言,Haskell。

Haskell和以往所学的计算机语言的最大区别就是它是一个纯函数式编程语言(pure functional programming language)。C语言,面向对象的JAVA和C++,大多数的脚本语言例如python,都是命令性语言(imperative language)。命令性语言的每一个表达式(statement)都是一个求值过程,整个程序就是在不断的下命令,从而让计算机去执行命令。函数式语言则像是在描述方法,方法所操作的对象不一定在方法定义时确定。这有点像C++中的泛型,不过泛型是C++的附加库,多态却是函数式语言的基础。

现在我还不能完全理解两种语言的区别,不过看起来函数式编程和符号运算有点相像。程序在描述算法而非命令。只有当需要求值的时候,算法才会将输入数据带入算法以获得一个结果,否则输出还是函数。哦,这也是个区别,函数在函数式语言中可以天然地作为输入或者输出,而命令式语言只能通过函数指针(或类似的方式,比如对象)来将函数作为另一个函数的输入。关于这一点,我的描述很苍白无力。看看这篇文章(http://www.aqee.net/2011/05/31/can-your-programming-language-do-this/)之后,也许能理解的好一点。

在国内我还从没听说过函数式编程,也许是由于我非本行的关系,也许计算机系有教吧。不过我还是学过一种函数式语言Lisp,只不过当时阮晓钢教授是拿来教授人工智能中的文字处理。

正在看一本叫做《Real world Haskell》的书,刚刚开始。稍微对这个语言有点不满意:它居然用每行前的的空白长度来判断函数块。直接造成了空格和Tab的混用能造成bug的问题。至少scheme在这点上好得多。但据说Haskell是当前最纯的函数式语言。

另一点比较怪的是,它的函数库并不用源代码,有点像Java的字节码,所以在Linux上安装ghc(Haskell的编译器)之后并找不到任何Haskell的源代码。也许我错了?Anyway,所有的库函数可以用这个网站查找(啊,函数在页内的排序也是乱的,还是用软件直接生成的,也太没规范了,不愧是学术界造的东西):http://haskell.org/ghc/docs/7.0-latest/html/libraries/index.html

Advertisements

Google+ invitation

借同学的光,也有了个google+的帐号,还有16个邀请名额,谁要的话用gmail给我写封信。啊,我认识的才可以哦。

一些Latex的小问题

昨天终于把博士论文的最终版送去装订了。

在博士论文的写作中又遇到了许多Latex的小问题,想想现在应该总结一下。比较乱,凑活看。

1. hyperref
曾经认为只有使用pdflatex才能使用hyperref包来生成超级连接和pdf的目录搜索页。现在发现这是个误解。
hyperref包的默认pdf生成工具是pdflatex,但它也支持latex+dvipdf/dvipdfm的方式。只不过需要配置一下。
在我的博士论文当中,hyperref包的使用如下:

\usepackage[
dvipdfm,
pdftitle={\thesistitle},
pdfauthor={\thesisauthor},
colorlinks=true,
linkcolor=black,
breaklinks=true,
urlcolor=blue,
citecolor=black
]{hyperref}

其中第一行dvipdfm则告诉hyperref最终的pdf生成工具是dvipdfm。hyperref会在生成的dvi文件中插入dvipdfm能够正确识别的注释符。
pdftitle和pdfauthor将会改变生成的pdf文件的标签页中的文件标题和作者。
colorlinks=true表明使用颜色来表示所有的链接(默认为不使用)
linkcolor=black设定内部链接使用黑色文本(默认为难看的红色)
breakline=true允许将长的url拆成多行(默认为禁止,长url将在一行显示,无论多长)
urlcolor=blue使用蓝色显示url(默认为粉色,??不符合一般网页定义)
citecolor=black引用用黑色显示(默认为绿色)
其他参数参看http://mirror.ctan.org/macros/latex/contrib/hyperref/doc/manual.pdf

2. booktabs
Latex传统的表格已经过时了。为了让表格更加美观,现在有了一个新的表格包— booktabs
这个包将覆盖原有的table关键字,基本上原有的tabular命令都可以使用,不过booktabs提供了一些新的命令,比如\toprule,\middlerule和\bottomrule。两种表格的风格比较参见http://en.wikibooks.org/wiki/LaTeX/Tables中的Proffessional tables小节

3. 显示源代码
有时候我们希望在文本中加入源代码。源代码和普通文本不同,代码往往用等宽字符显示才美观,而文本字体往往会使用非等宽字体来隐藏难看的字符间的不等空隙。
Latex本身就自带了一种等宽显示模式(verbatim),所有在\begin{verbatim}和\end{verbatim}之间显示的问题都将使用等宽字符显示。不过,所用的字体看起来就像原来的DOS的控制行显示字体,好像叫terminal字体。更令人抓狂的是,所有的加粗,斜体,颜色等等命令在verbatim环境中都会失效。也就是说,尽管代码能用等宽字体显示了,不过你也别想加粗关键字和用颜色显示注释。
其实,listings包提供了代码显示的支持。我所使用的配置如下:

\usepackage{listings}
\lstset{
  language=Verilog,
  basicstyle=\ttfamily\scriptsize
}

其中Verilog就表明了将显示的代码是Verilog HDL,这样listing能自动识别关键字并使用不同的格式显示。不过我的\ttfamily好像还是覆盖了关键字显示。仍然只能有一种字体格式。不过注释现在能自动斜体显示了。稍微有一点点遗憾。具体配置请参看http://mirror.ctan.org/macros/latex/contrib/listings/listings.pdf

4. 单位符号
为了统一各种单位的显示,比如byte/s,uJ, ^oC等等,我使用了SIunits包。该包定义了大部分的单位并用统一的格式显示单位和其数值。使用该包后,24 mm^2将写作\unit{24}{\milli\squaren\metre},然后latex就能正确显示。不过该包重定义了\square,和数学包中的\square冲突。配置SIunits使用squaren将迫使SIunits定义平方符号为\squaren
我的使用配置如下:

\usepackage[binary,squaren]{SIunits}

其中binary告诉SIunit支持和byte,bit相关的单位。如果有没有定义的单位,比如MByte/Node/s中的node就没有定义。可以直接在unit代码中写文字(\mega\byte\perNode\per\second)。

5. 对某些文字使用不同字体。
我们经常希望某些文字用不同的字体显示,比如说标题和页眉。Latex往往使用全局配置控制字体,换字体往往意味着换环境,比如进入数学模式。换字体在latex还真不是很容易。
我在我的论文中定义了一个新命令:

\newcommand{\arial}[1]{{\fontencoding{T1}\usefont{T1}{phv}{m}{n}{#1}}}

这样we \arial{are} human.中are就会使用arial显示。linux下面没有arial,而叫做Helvetica,一个瑞士人发明的。其实Arial反而是后来的,只不过我们windows用多了,不知道其实微软copy了Helvetica而已。我的命令中phv就是Helvetica。T1说明使用T1字体。字体是一个很复杂的问题,我自己还没太搞清楚。。。。在使用新字体的时候,准备好latex会爆出一大堆缺少文件,缺少map或字体不识别的问题。。。

6. 图片的多行标题显示
从没有想到原来多行显示图片标题居然会是个问题。在默认环境下,使用caption包,短于一行的标题会居中显示,长于一行的标题将会沾满整行然后在行尾断行。这都没有问题。不过,要是想在某个地方人为断行,这个就难了。比如说下面:

Assuming
this
is a Figure

Fig. The figure
caption

人为在figure后加上\\断行后,单行标题变成多行标题,所有行都会顶在行左,就出现了这种难看的样子。到现在我也没有发现有什么办法告诉Latex去居中显示整个标题块,好象是因为latex并不知道标题块有多宽。
这种的办法是配置caption包。我最终的配置:

\usepackage{caption}
\captionsetup{margin=20pt,format=hang,justification=justified}

其中margin告诉latex在标题块的两边都留20pt的空白,如果标题超长,至少多行不会直接顶在最左边。现在是有了20pt的整体缩进。后面的hang是告诉caption允许多行标题,如果出现多行,按照正常的多段文本处理(默认标题只有一段文字,禁止多段文字)。然后justified确定使用默认的问题对齐方式(两端对齐加短行靠左)。不过,这些特性仅仅在新的caption包中才支持。Fedora自带的texlive-2007不支持,需要单独安装最新的caption。后面再说这个问题。

7. 超长行的自动换行
以前没有注意到,原来latex的自动拆单词换行是依靠字典的。如果遇到latex不认识的单词,他就不会换行了。我就遇到如下的问题:

This is a dummy sentence.
I am going to show a longsentence
that latex does not recogn-
ise correctly and does not
how to hyphen it. It is left th-
ere as a super long line.

其中longsentence是一个latex不认识的单词,他就不会拆了(很愚蠢!)解决这种问题,需要两步:
1. 使用\usepackage[british]{babel}告诉latex用正确的字典去查单词,比如我就使用英式英语而非美式(默认)。然后对于长的自造单词,使用hyphenation告诉latex如何拆:

\hyphenation{long-sen-ten-ce net-works semi-conduc-tor meta-sta-bi-lity MU-TEX pi-pe-line}

8. 不想显示章节号的章节
我们往往会希望有些章节没有章节号,比如备注或者致谢。在我的论文中,我有备注。我希望备注和正文直接有一页纸显示备注,但是不希望该页成为论文的第四个部分(论文正文有三个部分了)。简单的将章节号去除,latex将认为该章节不存在,所以目录中就不会显示了,但这又是我不希望看到的。我希望有一个没有编号的第4部分,同时在目录中显示。以下的代码就能做到这点:

\appendix
\part*{Appendix}\label{part_appendix}
\addcontentsline{toc}{part}{Appendix}

\appendix显示备注开始,\part*{Appendix}定义了一个没有编号的部分,会以单独的一页纸显示Appendix的开始。不过该部分并不被latex认为是一个部分。所以后面的addcontentsline重新一部分的方式将Appendix加入目录。(不过,hyperref在pdf中的标签导航还是显示整个Appedix属于第3部分而不是单独的一个部分,不知道怎么搞。。。)

9. 孤行控制
在Word中我们只要选中孤行控制,Word就不会将一段的第一行或者最后一行放在不同的页面。Latex中好像没有相应的命令。Latex只是尽量防止孤行,当避免孤行会导致大量的页面空白的时候,Latex会放弃避免孤行。我们可以改变孤行的惩罚权重来告诉Latex我们更在乎孤行。有两个参数控制这些:

\widowpenalty=4000
\clubpenalty=4000

其中\widowpentalty是出现尾行分页所产生的惩罚值,\clubpenalty是出现首行分页的惩罚值。默认是150。我把他们都设成4000,就是告诉latex要更努力的减少孤行。如果设定惩罚为10000,就会完全的避免孤行,但是排版会很难看,因为latex会放弃一切的去排除孤行。

10. Tex-live 2011
Fedora的默认latex是tex-live 2007包,也就是说所有的包都是2007年之前的,已经很落后了。从Fedora 13开始,Fedora提供了tex-live 2011和tex-live 2010的开发包支持。参看http://fedoraproject.org/wiki/Features/TeXLive,那里提供了更新到tex-live新版本的rpm yum升级包。安装之后就可以使用yum来自动更新所有的tex-live包。我个人一直在fedora 14上使用tex-live 2011,除了有时候yum 升级会出现版本冲突问题(他们一直在更新,所以难免会有版本冲突,往往过几天就没了,继续升级就好),没有发现有什么问题,一切OK。非常推荐升级tex-live。