Functional Programming
description
Transcript of Functional Programming
Functional Programming
12 Haskell
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 Hashall
makeList = 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.141592653589793
The 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 onList
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.hsmodule Testwherex = 5y = (6, "Hello")z = x * fst y Prelude> :l Test.hs Test> Test> x
5 Test> y
(6,"Hello") Test> z
30
Source Code Files
main = putStrLn "Hello World“ C:\ghc> ghc –make c:\\xxx\\test.hs -o test.exe
or Prelude> :! ghc --make c:\\xxx\\test.hs -o test.exe
C:\ghc> test.exeHello World
Functions Test.hsmodule Test -- 注意大寫 wheresig x = if x < 0 -- 注意縮排 then -1 else if x > 0 then 1 else 0 Test> sig 5
1 Test> sig 0
0 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.hsmodule 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) 2
1
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 versionint 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);} Haskellfactorial 1 = 1factorial n = n * factorial (n-1)
1 1!
( 1)! otherwisen
nn n
Recursion
Exercise
exponent a 1 = a exponent a b = a * exponent a (b-1)
1
1 otherwise
bb
a ba
a a
Interactivity Test.hs module Name where import IO name = do --do specifies the order of operations hSetBuffering stdin LineBuffering putStrLn "Please enter your name: " name <- getLine putStrLn ("Hello, " ++ name ++ ", how are you?") Name > name
Please 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*x
f = \x y -> 2*x + y
Example Guess.hsmodule Main whereimport IOimport Randommain = do hSetBuffering stdin LineBuffering num <- randomRIO (1::Int, 100) putStrLn "I’m thinking of a number between 1 and 100" doGuessing numdoGuessing 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!"