《Two Dozen Short Lessons in Haskell》(Copyright © 1995, 1996, 1997 by Rex Page,有人翻译为Haskell二十四学时教程,该书如果不用于赢利,可以任意发布,但需要保留他们的copyright)这本书是学习 Haskell的一套练习册,共有2本,一本是问题,一本是答案,分为24个章节。在这个站点有PDF文件。几年前刚开始学习Haskell的时候,感觉前几章还可以看下去,后面的内容越来越难以理解。现在对函数式编程有了一些了解后,再来看这些题,许多内容变得简单起来了。
初学Haskell之前一定要记住:
把你以前学习面向过程的常规的编程语言,如Pascal、C、Fortran等等统统忘在脑后,函数式编程完全是不一样的编程模型,用以前的术语和思维来理解函数式编程里的概念,只会让你困惑和迷茫,会严重地影响你的学习进度。
这个学习材料内容太多,想把整书全面翻译下来非常困难,只有通过练习题将一些知识点串起来,详细学习Haskell还是先看其它一些入门书籍吧,这本书配套着学学还是不错的。
函数有类型,它的参数有类型,返回值也有类型。函数类型的定义如下:
多态能够用同一个函数作用在不同的参数上,比如reverse函数,可以把一列整数反序,也可以把一列字符串反序。
1 Polymorphic functions
a change the types of their arguments
b combine data of different types
c can operate on many types of arguments
d gradually change shape as the computation proceeds
2 The function toUpper takes a letter of the alphabet (a value of type Char) and delivers the upper-case version of
the letter. What is the type of toUpper?
a polymorphic
b Char -> Char
c lower -> upper
d cannot be determined from the information given
3 A value of type [a] is
a a sequence with elements of several different types
b a sequence with some of its elements omitted
c a sequence whose elements are also sequences
d a sequence whose elements are all of type a
4 A function of type [a] -> [[a]] could
a transform a character into a string
b deliver a substring of a given string
c deliver a string like its argument, but with the characters in a different order
d transform a string into a sequence of substrings
5 Suppose that for any type a in the class Ord, pairs of values of type a can be compared using the operator <.
A function of type Ord a => [a] -> [a] could
a rearrange the elements of a sequence into increasing order
b deliver a subsequence of a given sequence
c both of the above
d none of the above
6 Suppose Ord is the class described in the preceding question. What is the type of the operator <.
a Ord a => a -> a -> Bool
b Ord a => a -> Bool
c Ord a => a -> Char
d Ord a => a -> [Char]
7 The equality class
a includes all Haskell types
b is what makes functions possible
c is what makes comparison possible
d excludes function types
8 A function with the type Eq a => a -> Bool
a requires an argument with the name a
b delivers True on arguments of type a
c is polymorphic
d must be equal to a
9 If the type of f has three arrows in it, then the type of f x has
a one arrow in it
b two arrows in it
c three arrows in it
d four arrows in it
10 A polymorphic function
a has more than one argument
b has only one argument
c may deliver values of different types in different formulas
d can morph(改变) many things at once
=========================================================
答
案
在
下
面
=========================================================
1 c
多态函数并不改变它的参数的类型,haskell是类型要求严格的语言,它的参数接受进来是什么类型,就是什么类型,不能动态改变。
combline data of different types,多态函数并不负责将多种类型的数据组合在一起,后面讲的tuple元组能够完成这个任务。
haskell中的多态感觉与C#等高级语言中的泛型差不多,例如C#中List <T>中的T代表任意的一种class,而haskell中的函数定义reverse :: [a] -> [a],其中的a也是代表任意一种类型,所以选c。
多态函数在计算过程中并不改变形态。
2 b
toUpper只能接受Char类型的数值,并且得到Char类型(大写字母)的数值,所以类型就是Char –> Char
3 d
在类型定义里[a]表示一个列表,其中每个元素是一种类型Type,这个类型称为a。如果a是Char类型,那么[a]就是[Char],如果a是Int,那么[a]就是[Int],由于[a]是一个列表,所以它里面的元素一定都是同一种类型。
4 d
函数定义:[a]->[[a]],如果a代表Char,则输入参数的类型是[Char],即一个字符串String,而输出类型就是[[Char]],也就是[String],即一个列表,列表中的元素是字符串。
5 c
在Haskell中有2个术语,type和class,type对应于c#语言中的类class,而class对应于C#于的接口interface。
Ord是Haskell中的一个可用于比较的类,有点类似于C#中的IComparable接口。
对于属于Ord中的类型a和b,两者是可以比较大小的。
一个函数的类型是:Ord a => [a] -> [a]
比如这个函数名叫f,完整的函数声明应该是:
f :: Ord a => [a] -> [a]
这种函数声明类似于C语言中的函数声明,告诉编译器这个函数接受几个参数、参数的类型、函数的返回类型等。
在::之前是函数名称,函数声明里出现a, b, c ...,表示这是一个多态函数,在=>之前的Ord a表示a这种类型Type必须可以比较大小。
[a] -> [a]表示接受一个参数,这个参数是一个列表,列表中的元素可以排序。返回值也是一个列表,列表中的元素当然也支持排序。
所以这个函数能够得到一个列表,列表中的元素可以排序,也可以是列表的子列表。
6 a
Ord中的类型可以比较大小,函数(<)接收2个输入参数,返回布尔值。
在ghci中运行:type (<)
得到:
(<) :: Ord a => a -> a -> Bool
7 d?
这个题的答案是d,但我选的是c,暂时还没弄明白。
8 c
Eq a => a –> Bool 这里面有a这样的符号,表示是一种多态函数,a是一种Eq中的一种类型。这个函数接收一个参数,这个参数可以判断是否与其它实例相等(即可以进行'=='这种运算符操作),返回值是一个布尔值。
书中判断回文的函数就是这种函数:
isPalindrome :: Eq a => [a] –> Bool
isPalindrome phrase = (phrase == reverse phrase)
由于这是个多态函数,所以不仅仅是字符串"abcba"的回文判断,[1,2,3,2,1]这样的数字列表也是回文。
9 b
f有三个箭头,则f x的类型就有两个箭头。
举个例子:
f :: Char –> Char –> Char –> [Char]
f x y z = [ x, y, z]
这个函数可以把三个字符连接成一个字符串,有3个箭头。
那么f x 就只能再接受2个参数,所以其类型定义只有2个箭头。
f x :: Char –> Char –> [Char]
10 c
多态函数与参数个数没有关系
多态函数可以应用于不同的类型,此时的返回类型也可能不同。
《Two Dozen Short Lessons in Haskell》学习(一)Hello World
《Two Dozen Short Lessons in Haskell》学习(二)Definitions
《Two Dozen Short Lessons in Haskell》学习(三)How to Run Haskell Programs
《Two Dozen Short Lessons in Haskell》学习(四)List Comprehensions
《Two Dozen Short Lessons in Haskell》学习(五)Function Composition and Currying
《Two Dozen Short Lessons in Haskell》学习(六)Patterns of Computation – Composition, Folding, and Mapping
《Two Dozen Short Lessons in Haskell》学习(七)- Types
《Two Dozen Short Lessons in Haskell》学习(八)- Function Types, Classes, and Polymorphism
《Two Dozen Short Lessons in Haskell》学习(九)- Types of Curried Forms and Higher Order Functions
《Two Dozen Short Lessons in Haskell》学习(十)- Private Definitions — the where-clause
《Two Dozen Short Lessons in Haskell》学习(十一)- Tuples
《Two Dozen Short Lessons in Haskell》学习(十二) 数值相关的类
《Two Dozen Short Lessons in Haskell》学习(十三)迭代及重复的常规模式
《Two Dozen Short Lessons in Haskell》学习(十四)截断序列和惰性求值
《Two Dozen Short Lessons in Haskell》学习(十五)- Encapsulation — modules
《Two Dozen Short Lessons in Haskell》学习(十六)- Definitions with Alternatives
《Two Dozen Short Lessons in Haskell》学习(十七) - 模块库
《Two Dozen Short Lessons in Haskell》学习(十八) - 交互式键盘输入和屏幕输出
《Two Dozen Short Lessons in Haskell》学习(十九) - 文件输入与输出
《Two Dozen Short Lessons in Haskell》学习(二十)- 分数
《Two Dozen Short Lessons in Haskell》学习(二十一)- 在形式参数中使用模式匹配
《Two Dozen Short Lessons in Haskell》学习(二十二)- 递归
第23章没有习题。