1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
Gentle Introduction to Haskell 98, Online Supplement
Part 7
Covers Sections 3, 3.1
> module Part7() where
> import Prelude hiding (map)
Section: 3 Functions
> 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:
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
> e4 :: [Int]
> e4 = map inc [1,2,3]
Heres a more complex example. Define flist to be a list of functions:
> 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>>]
Now, define a function which takes a function and returns its value
when applied to the constant 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].
Section: 3.1 Lambda Abstractions
The symbol \ is like `lambda' in lisp or scheme.
Anonymous functions are written as \ arg1 arg2 ... argn -> body
Instead of naming every function, you can code it inline with this
notation:
> 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!!
This is identical to e5 except that the applyTo1 function has no name.
Function arguments on the left of an = are the same as lambda on the
right:
> 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.
Continued in part8.lhs
|