Section: 3 Functions

第 3 节 函数

add :: Int -> Int -> Int
add x y = x+y
e1 :: Int
e1 = add 1 2

This Int -> Int is the latter part of the signature of add:

这个 Int -> Int 是 add 签名的后半部分:

add :: Int -> (Int -> Int)
inc :: Int -> Int
inc = add 1
e2 :: Int
e2 = inc 3
map :: (a->b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : (map f xs)
e3 :: [Int]
e3 = map (add 1) [1,2,3]

This next definition is the equivalent to e3

下面这个定义与 e3 等价。

e4 :: [Int]
e4 = map inc [1,2,3]

Heres a more complex example. Define flist to be a list of functions:

来看一个更复杂的例子。把 flist 定义为一个函数的列表:

flist :: [Int -> Int]
flist = map add [1,2,3]

This returns a list of functions which add 1, 2, or 3 to their input. Haskell should print flist as something like [<<function>>,<<function>>,<<function>>]

这返回一个函数列表,这些函数分别把输入加 1、2 或 3。Haskell 应当把

flist 打印成类似这样的东西:

[<<function>>,<<function>>,<<function>>]

Now, define a function which takes a function and returns its value when applied to the constant 1:

现在,定义一个函数:它接受一个函数,返回该函数作用于常量 1 时的值:

applyTo1 :: (Int -> a) -> a
applyTo1 f = f 1
e5 :: [Int]
e5 = map applyTo1 flist  -- Apply each function in flist to 1

If you want to look at how the type inference works, figure out how the signatures of map, applyTo1, and flist combine to yield [Int].

如果你想研究类型推断是如何工作的,弄清楚 map、applyTo1 和 flist 的

签名是如何组合得出 [Int] 的。

Section: 3.1 Lambda Abstractions

第 3.1 节 Lambda 抽象

The symbol \ is like lambda in lisp or scheme.

符号 \ 就像 lisp 或 scheme 中的 lambda。

Anonymous functions are written as \ arg1 arg2 ... argn -> body Instead of naming every function, you can code it inline with this notation:

匿名函数写作 \ arg1 arg2 ... argn -> body。不必给每个函数都起名字,

你可以用这种记法把它们内联地写出来:

e6 = map (\f -> f 1) flist

Be careful with the syntax here. \x->\y->x+y parses as \ x ->\ y -> x + y. The ->\ is all one token. Use spaces!!

这里的语法要小心。\x->\y->x+y 会被解析为 \ x ->\ y -> x + y。

->\ 是一个完整的词法单元。要用空格!!

This is identical to e5 except that the applyTo1 function has no name.

这与 e5 完全相同,只是 applyTo1 函数没有了名字。

Function arguments on the left of an = are the same as lambda on the
right:

等号左边的函数参数与等号右边的 lambda 是等价的:

add' = \x y -> x+y    -- identical to add
inc' = \x -> x+1     -- identical to inc

As with ordinary function, the parameters to anonymous functions can be patterns:

与普通函数一样,匿名函数的参数也可以是模式:

e7 :: [Int]
e7 = map (\(x,y) -> x+y) [(1,2),(3,4),(5,6)]

Functions defined by more than one equation, like map, cannot be converted to anonymous lambda functions quite as easily - a case statement is also required. This is discussed later.

由多条方程定义的函数(如 map),不能如此轻易地转换成匿名 lambda

函数——还需要 case 表达式。这个后面再讲。