270 likes | 504 Views
12 Haskell. Functional Programming. Language Basics. ftp://web.ntnu.edu.tw/WWW/func_prog/ghc-6-8-2.zip Haskell is Lazy evaluated Case-sensitive Purely functional. Language Basics. Lazy evaluated
E N D
12 Haskell Functional Programming
Language Basics • ftp://web.ntnu.edu.tw/WWW/func_prog/ghc-6-8-2.zip • Haskell is • Lazy evaluated • Case-sensitive • Purely functional
Language Basics • Lazy evaluated • No computation takes place unless it is forced to take place when the result of that computation is used • Pseudo-codeList makeList() { List current = new List(); current.value = 1; current.next = makeList(); return current; } It attempt to get a value out of it. This leads to an infinite loop • HashallmakeList = 1 : makeList 把makelist定義為element1加上makelist
Language Basics • Purely functional • Functions that do not have side effects are called pure • If you have a value x • you must not think of x as a register, a memory location or anything else of that nature • x is simply a name, just as “Mary” is your name • You cannot arbitrarily decide to store a different person in my name any more than you can arbitrarily decide to store a different value in x • A call like x = x + 1 is called destructive • Destructive update does not exist in Haskell
Evaluating expressions • Prelude> sum [1..10]55 • Prelude> 5+2*311 • Prelude> sin 0.30.29552020666134 • Prelude> length [1,5,9,3]4 • Prelude> reverse [1..10][10,9,8,7,6,5,4,3,2,1]
Variables • Prelude> let pi = 3.14159265358979323846264338327950 • Prelude> pi 3.141592653589793The missing digits are just skipped when displaying the value • Prelude> pi * 5^2 78.53981633974483 • Prelude> pi * 25^2 1963.4954084936207 • Prelude> let r = 25.0 Prelude> let area = pi * r ^ 2 Prelude> area 1963.4954084936207
Pairs, Triples and More • Prelude> (5,3)(5,3) • The first element of a pair need not have the same type as the second element • Prelude> fst (5, "hello")5 • Prelude> snd (5, "hello")"hello“ • Exercise Use a combination of fst and snd to extract the character out of the tuple ((1,’a’),"foo")
Lists • The primary limitation of tuples • hold only a fixed number of elements: pairs hold two, triples hold three, and so on • List • Hold an arbitrary number of elements • Prelude> [1,2][1,2] • Prelude> [1,2,3][1,2,3]
Lists • : cons • Prelude> 0:[1,2][0,1,2] • Prelude> 5:[1,2,3,4] • [5,1,2,3,4] • Prelude> 5:1:2:3:4:[][5,1,2,3,4] • If we write something using the [5,1,2,3,4] notation, the compiler simply translates it to the expression using (:) and []
Lists • Tuples are heterogeneous • Lists must be homogenous • Prelude> [(1,1),(2,4),(3,9),(4,16)][(1,1),(2,4),(3,9),(4,16)] • Prelude> ([1,2,3,4],[5,6,7])([1,2,3,4],[5,6,7]) • Prelude> length [1,2,3,4,10]5 • Prelude> head [1,2,3,4,10]1 • Prelude> length (tail [1,2,3,4,10])4
Strings • String is simply a list of Chars • Prelude> ’H’:’e’:’l’:’l’:’o’:[]"Hello“ • ++ • Prelude> "Hello " ++ "World“"Hello World“ • Prelude> "Five squared is " ++ show (5*5)"Five squared is 25"
Simple List Functions • Map • Takes as arguments a list of values and a function that should be applied to each of the values • Prelude> map Char.toUpper "Hello World“"HELLO WORLD“ • Filter • Remove certain elements from a list depending on their value • Prelude> filter Char.isLower "Hello World“"elloorld“ • Foldr • Replaces occurences of the list cons operator (:) with the function parameter and replaces the empty list constructor ([]) with the initial value • Prelude> foldr (+) 0 [3,8,12,5]28
Simple List Functions • Prelude> foldr (*) 1 [4,8,5]160 • Prelude> foldr (-) 1 [4,8,5]0 • foldr (-) 1 [4,8,5] ==> 4 - (foldr (-) 1 [8,5]) ==> 4 - (8 - foldr (-) 1 [5]) ==> 4 - (8 - (5 - foldr (-) 1 [])) ==> 4 - (8 - (5 - 1)) ==> 4 - (8 - 4) ==> 4 - 4 ==> 0
Simple List Functions • Foldl • Goes the other way and effectively produces the opposite bracketing • Prelude> foldl (+) 0 [3,8,12,5]28 • Prelude> foldl (-) 1 [4,8,5]-16 • foldl (-) 1 [4,8,5] ==> foldl (-) (1 - 4) [8,5] ==> foldl (-) ((1 - 4) - 8) [5] ==> foldl (-) (((1 - 4) - 8) - 5) [] ==> ((1 - 4) - 8) - 5 ==> ((-3) - 8) - 5 ==> (-11) - 5 ==> -16
Simple List Functions • Exercise Use map to convert a string into a list of booleans, each element in the new list representing whether or not the original element was a lower-case character.That is, it should take the string “aBCde” and return [True,False,False,True,True].
Source Code Files • test.hs module Test where x = 5 y = (6, "Hello") z = x * fst y • Prelude> :l Test.hs • Test> • Test> x5 • Test> y(6,"Hello") • Test> z30
Source Code Files • main = putStrLn "Hello World“ • C:\ghc> ghc –make c:\\xxx\\test.hs -o test.exeor Prelude> :! ghc --make c:\\xxx\\test.hs -o test.exe • C:\ghc> test.exeHello World
Functions • Test.hs module Test --注意大寫 where sig x = if x < 0 --注意縮排 then -1 else if x > 0 then 1 else 0 • Test> sig 51 • Test> sig 00 • Test> sig (5-10)-1 • Test> sig (-1)-1
Functions • f x = case x of 0 -> 1 1 -> 5 2 -> 2 _ -> -1 • f x = case x of { 0 -> 1 ; 1 -> 5 ; 2 -> 2 ; _ -> 1 } • f x = case x of { 0 -> 1 ; 1 -> 5 ; 2 -> 2; _ -> 1 } • f 0 = 1 f 1 = 5 f 2 = 2 f _ = -1
Functions • Test.hs module Test where--注意縮排 signum2 x = if x < 0 then -1 else if x > 0 then 1 else 0 f x = case x of 0 -> 1 1 -> 5 2 -> 2 _-> -1 • Prelude > (sig . f) 21
Functions • roots a b c = let det = sqrt (b*b - 4*a*c) in ((-b + det) / (2*a), (-b - det) / (2*a)) • roots a b c = let det = sqrt (b*b - 4*a*c) twice_a = 2*a in ((-b + det) / twice_a, (-b - det) / twice_a)
Recursion • Imperative version int factorial(int n) { int fact = 1; for (int i=2; i <= n; i++) fact = fact * i; return fact; } int factorial(int n) { if (n == 1) return 1; else return n * factorial(n-1); } • Haskell factorial 1 = 1 factorial n = n * factorial (n-1)
Recursion • Exercise • exponent a 1 = a exponent a b = a * exponent a (b-1)
Interactivity • Test.hs module Name where import IO name = do --do specifies the order of operations hSetBufferingstdinLineBuffering putStrLn "Please enter your name: " name <- getLine putStrLn ("Hello, " ++ name ++ ", how are you?") • Name > namePlease enter your name:MaryHello, Mary, how are you?Name>
Lambda function • Prelude > (\x->2*x)2 • Prelude> map (\x -> x*x) [1..10][1, 4, 9, 16, 25, 36, 49, 64, 81, 100] • square = \x -> x*xf = \x y -> 2*x + y
Example • Guess.hs module Main where import IO import Random main = do hSetBufferingstdinLineBuffering num <- randomRIO (1::Int, 100) putStrLn "I’m thinking of a number between 1 and 100" doGuessing num doGuessing num = do putStrLn "Enter your guess:" guess <- getLine let guessNum = read guess if guessNum < num then do putStrLn "Too low!" doGuessing num else if guessNum> num then do putStrLn "Too high!" doGuessing num else do putStrLn "You Win!"