dr. philip cannata 1 programming languages haskell
DESCRIPTION
Dr. Philip Cannata 3 Haskell: /lusr/bin/hugs, should be in your default $PATH or for windows, download and install winhugs at $ hugs __ __ __ __ ____ ___ _________________________________________ || || || || || || ||__ Hugs 98: Based on the Haskell 98 standard ||___|| ||__|| ||__|| __|| Copyright (c) ||---|| ___|| World Wide Web: || || Bugs: || || Version: _________________________________________ Haskell 98 mode: Restart with command line option -98 to enable extensions Type :? for help Hugs> :load 09H1 Main> To load the file “09H1.hs” from the directory in which you started hugsTRANSCRIPT
Dr. Philip Cannata 1
Programming Languages
Haskell
Dr. Philip Cannata 2
A programming language is a language with a well-defined syntax (lexicon and grammar), type system, and semantics that can be used to implement a set of algorithms.
Haskell
Dr. Philip Cannata 3
Haskell: /lusr/bin/hugs, should be in your default $PATH or for windows, download and install winhugs at http://cvs.haskell.org/Hugs/pages/downloading.htm
$ hugs__ __ __ __ ____ ___ _________________________________________|| || || || || || ||__ Hugs 98: Based on the Haskell 98 standard||___|| ||__|| ||__|| __|| Copyright (c) 1994-2005||---|| ___|| World Wide Web: http://haskell.org/hugs|| || Bugs: http://hackage.haskell.org/trac/hugs|| || Version: 20051031 _________________________________________
Haskell 98 mode: Restart with command line option -98 to enable extensions
Type :? for helpHugs> :load 09H1Main>
To load the file “09H1.hs” from the directory in
which you started hugs
Dr. Philip Cannata 4
Hugs> 2 * 4 ^232Hugs> 8^264Hugs> (2 * 4) ^ 264Hugs> 2 + 4 ^ 218Hugs> 2 ^ 2001606938044258990275541962092341162602522202993782792835301376Hugs> True && FalseFalseHugs> True || FalseTrueHugs> 3 < 5TrueHugs> 'c' < 'p'TrueHugs> 'c' > 'p'FalseHugs> "tree" < "rock"FalseHugs> "tree" > "rock"True
Haskell Expression
Number Expressions
Boolean Expressions
Character Expressions
String Expressions
Dr. Philip Cannata 5
Hugs> ("dog", "cat", 5)("dog","cat",5)
Hugs> ["dog", "cat", 5]ERROR - Cannot infer instance*** Instance : Num [Char]*** Expression : ["dog","cat",5]
Hugs> ["dog", "cat", "5"]["dog","cat","5"]
Hugs> 1 : [][1]
Hugs> 1 : [2,3,4][1,2,3,4]
[expression | generator]Hugs> [2 * x ^ 2 | x <- [1, 2, 3 ,4]][2,8,18,32]
Hugs> [x * y | (x, y) <- [(1, 2), (3, 4), (5, 6)]][2,12,30]
Haskell Basic Data Structures
Tuples
Lists
List Construction
List Comprehension
Dr. Philip Cannata 6
Hugs> [(x, y) | x <- [1, 3 .. 6], y <- ['a', 'b', 'c', 'd']][(1,'a'),(1,'b'),(1,'c'),(1,'d'),(3,'a'),(3,'b'),(3,'c'),(3,'d'),(5,'a'),(5,'b'),(5,'c'),(5,'d')]
Hugs> [(x, y) | x <- [1..4], y <- [1..4]][(1,1),(1,2),(1,3),(1,4),(2,1),(2,2),(2,3),(2,4),(3,1),(3,2),(3,3),(3,4),(4,1),(4,2),(4,3),(4,4)]
Hugs> [(x, y) | x <- [0..4], y <- [0..4], x < y][(0,1),(0,2),(0,3),(0,4),(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]
Hugs> [(x, y) | x <- [0..4], y <- [0..4], x > y][(1,0),(2,0),(2,1),(3,0),(3,1),(3,2),(4,0),(4,1),(4,2),(4,3)]
Hugs> [x | x <- [1..100], y <- [1..100], 72 == x * y][1,2,3,4,6,8,9,12,18,24,36,72]
Haskell Basic Data Structures continued
List Comprehension
Cross product
“<“ and “>” Relation
Factors of 72
Dr. Philip Cannata 7
Main> [empno | (empno, _, _, _, _, _, _) <- emp][7839,7698,7782,7566,7788,7902,7369,7499,7521,7654,7844,7876,7900,7934]Main> [empno | (empno, _, _, _, _, sal, _) <- emp, sal > 4000][7839]Main> [empno | (empno, _, _, _, _, sal, _) <- emp, sal > 2000][7839,7698,7782,7566,7788,7902]
Haskell Basic Data Structures - continued
List Comprehension
Database Query
Dr. Philip Cannata 8
Hugs> :type productproduct :: Num a => [a] -> a
Hugs> product [ 2, 3, 4 ]24
Hugs> product [ x | x <- [1..10]]3628800
Hugs> :type (+)(+) :: Num a => a -> a -> a
Hugs> 3 + 58
Hugs> (+) 3 58
Hugs> (\ x -> x ^ 2 + 4) 529
Haskell Functions
product Function
(+) Operator – an Operator is a 2-ary Function
lambdas
Dr. Philip Cannata 9
Hugs> :type notnot :: Bool -> Bool
Hugs> not TrueFalse
Hugs> :type mapmap :: (a -> b) -> [a] -> [b]
Hugs> map sqrt [ 1, 4, 9, 10 ][1.0,2.0,3.0,3.16227766016838]
Hugs> map (\ x -> x + 2) [ 1, 2, 3, 4][3,4,5,6]
Hugs> :type headhead :: [a] -> a
Hugs> head [5, 4, 3, 2, 1]5
Haskell Pattern Matching
not :: Bool Boolnot False = Truenot True = False
map :: (a -> b) -> [a] -> [b] map _ [] = []map f (x:xs) = f x : map f xs
head :: [a] -> a head = ( \(x:xs) -> x)
Dr. Philip Cannata 10
Hugs> if True then 6 else 86Hugs> if False then 6 else 88
Hugs> 2 + let x = sqrt 9 in (x + 1) * (x - 1)10.0
Haskell Conditional Expressions
Let Expressions (i.e., local variables)
not :: Bool Boolnot False = Truenot True = False
Let assignment assignment . . . in (expression)
Dr. Philip Cannata 11
v = 1/0testLazy x = 2 + 10testLazy1 x = 2 / x
Hugs> v1.#INF
Hugs > testLazy 2212
Hugs > testLazy v12
Hugs > testLazy1 229.090909090909091e-2
Hugs > testLazy1 v0.0
Hugs > (\x -> let y = x in (2 / y)) (1/0)0.0
Hugs > (\x -> let y = x in (2 / y)) (0)1.#INF
Lazy Evaluation
Dr. Philip Cannata 12
Propositions:
Statements that can be either True or False
Logical Operators: • Negation: not
not :: Bool-> Boolnot True = False not False = True
• Conjunction: &&(&&) :: Bool-> Bool-> BoolFalse && x = False True && x = x
• Disjunction: ||(||) :: Bool-> Bool-> BoolTrue || x = TrueFalse || x = x
Propositional Logic
Logical Operators: • Implication (if – then): ==> Antecedent ==> Consequent
(==>) :: Bool -> Bool -> Boolx ==> y = (not x) || y
• Equivalence (if, and only if): <=>(<=>) :: Bool -> Bool -> Boolx <=> y = x == y
• Not Equivalent <+> (<+>) :: Bool -> Bool -> Boolx <+> y = x /= y
Dr. Philip Cannata 13
Truth tables: P && QP || Qnot PP ==> QP <=> QP <+> Q
P Q P && QFalse False FalseFalse True FalseTrue False FalseTrue True True
P Q P || QFalse False FalseFalse True TrueTrue False TrueTrue True True
P PFalse TrueTrue False
P Q PQFalse False TrueFalse True TrueTrue False FalseTrue True True P Q
P<=>QFalse False TrueFalse True FalseTrue False FalseTrue True True
P Q P <+> QFalse False FalseFalse True TrueTrue False TrueTrue True False
Dr. Philip Cannata 14
Proposition (WFF): ((P Q)((P)Q)) P Q
False False
False True
True False
True True
False
True
True
True
(P Q) (P)
True
True
False
False
((P)Q)
False
True
True
True
((PQ)((P)Q))
False
True
True
True
Some True: prop is Satisfiable*If they were all True: Valid / Tautology
All False: Contradiction (not satisfiable*)
*Satisfiability was the first known NP-complete problem
If prop is True when all variables are True:P, Q ((PQ)((P)Q))
A Truthdouble turnstile
Reasoning with Truth Tables
Dr. Philip Cannata 15
truthTable :: (Bool -> Bool -> Bool) -> [Bool]truthTable wff = [ (wff p q) | p <- [True,False], q <- [True,False]]
tt = (\ p q -> not (p ==> q))
Hugs> :load 10Logic.hsLOGIC> :type tttt :: Bool -> Bool -> BoolLOGIC> truthTable tt[False,True,False,False]LOGIC> or (truthTable tt)TrueLOGIC> and (truthTable tt)False
Truth Table Application
Dr. Philip Cannata 16
Satisfiable: Are there well formed propositional formulas that return True for some input?
satisfiable1 :: (Bool -> Bool) -> Boolsatisfiable1 wff = (wff True) || (wff False)
satisfiable2 :: (Bool -> Bool -> Bool) -> Boolsatisfiable2 wff = or [ (wff p q) | p <- [True,False], q <- [True,False]]
satisfiable3 :: (Bool -> Bool -> Bool -> Bool) -> Boolsatisfiable3 wff = or [ (wff p q r) | p <- [True,False], q <- [True,False], r <- [True,False]]
( \ p -> not p)( \ p q -> (not p) || (not q) )( \ p q r -> (not p) || (not q) && (not r) )
Define these first
infix 1 ==>
(==>) :: Bool -> Bool -> Boolx ==> y = (not x) || y
infix 1 <=>
(<=>) :: Bool -> Bool -> Boolx <=> y = x == y
infixr 2 <+>
(<+>) :: Bool -> Bool -> Boolx <+> y = x /= y
Dr. Philip Cannata 17
Validity (Tautology): Are there well formed propositional formulas that return True no matter what their input values are?
valid1 :: (Bool -> Bool) -> Boolvalid1 wff = (wff True) && (wff False)
valid2 :: (Bool -> Bool -> Bool) -> Boolvalid2 wff = (wff True True) && (wff True False) && (wff False True) && (wff False False)
( \ p -> p || not p ) -- Excluded Middle( \ p -> p ==> p )( \ p q -> p ==> (q ==> p) )( \ p q -> (p ==> q) ==> p )
Dr. Philip Cannata 18
Contradiction (Not Satisfiable): Are there well formed propositional formulas that return False no matter what their input values are?
contradiction1 :: (Bool -> Bool) -> Boolcontradiction1 wff = not (wff True) && not (wff False)
contradiction2 :: (Bool -> Bool -> Bool) -> Boolcontradiction2 wff = and [not (wff p q) | p <- [True,False], q <- [True,False]]
contradiction3 :: (Bool -> Bool -> Bool -> Bool) -> Boolcontradiction3 wff = and [ not (wff p q r) | p <- [True,False], q <- [True,False], r <- [True,False]]
( \ p -> p && not p)( \ p q -> (p && not p) || (q && not q) )( \ p q r -> (p && not p) || (q && not q) && (r && not r) )
Dr. Philip Cannata 19
Truth: Are there well formed propositional formulas that return True when their input is True
truth1 :: (Bool -> Bool) -> Booltruth1 wff = (wff True)
truth2 :: (Bool -> Bool -> Bool) -> Booltruth2 wff = (wff True True)
( \ p -> not p)
( \ p q -> (p && q) || (not p ==> q))
( \ p q -> not p ==> q)
( \ p q -> (not p && q) && (not p ==> q) )
Dr. Philip Cannata 20
Equivalence:logEquiv1 :: (Bool -> Bool) -> (Bool -> Bool) -> BoollogEquiv1 bf1 bf2 = (bf1 True <=> bf2 True) && (bf1 False <=> bf2 False)
logEquiv2 :: (Bool -> Bool -> Bool) -> (Bool -> Bool -> Bool) -> BoollogEquiv2 bf1 bf2 = and [(bf1 r s) <=> (bf2 r s) | r <- [True,False], s <- [True,False]]
logEquiv3 :: (Bool -> Bool -> Bool -> Bool) -> (Bool -> Bool -> Bool -> Bool) -> BoollogEquiv3 bf1 bf2 = and [(bf1 r s t) <=> (bf2 r s t) | r <- [True,False], s <- [True,False], t <- [True,False]]
formula3 p q = p formula4 p q = (p <+> q) <+> qformula5 p q = p <=> ((p <+> q) <+> q)
*Haskell> logEquiv2 formula3 formula4True*Haskell> logEquiv2 formula4 formula5False
Dr. Philip Cannata 21
Equivalence continued:
logEquiv1 id (\ p -> not (not p))logEquiv1 id (\ p -> p && p) logEquiv1 id (\ p -> p || p) logEquiv2 (\ p q -> p ==> q) (\ p q -> not p || q) logEquiv2 (\ p q -> not (p ==> q)) (\ p q -> p && not q) logEquiv2 (\ p q -> not p ==> not q) (\ p q -> q ==> p) logEquiv2 (\ p q -> p ==> not q) (\ p q -> q ==> not p) logEquiv2 (\ p q -> not p ==> q) (\ p q -> not q ==> p) logEquiv2 (\ p q -> p <=> q) (\ p q -> (p ==> q) && (q ==> p))logEquiv2 (\ p q -> p <=> q) (\ p q -> (p && q) || (not p && not q))logEquiv2 (\ p q -> p && q) (\ p q -> q && p) logEquiv2 (\ p q -> p || q) (\ p q -> q || p) logEquiv2 (\ p q -> not (p && q)) (\ p q -> not p || not q) logEquiv2 (\ p q -> not (p || q)) (\ p q -> not p && not q) logEquiv3 (\ p q r -> p && (q && r)) (\ p q r -> (p && q) && r) logEquiv3 (\ p q r -> p || (q || r)) (\ p q r -> (p || q) || r) logEquiv3 (\ p q r -> p && (q || r)) (\ p q r -> (p && q) || (p && r)) test9b logEquiv3 (\ p q r -> p || (q && r)) (\ p q r -> (p || q) && (p || r))
-- Idempotence-- Idempotence-- Implication-- Contrapositive-- Contrapositive-- Contrapositive-- Contrapositive -- Commutativity-- Commutativity-- deMorgan-- deMorgan-- Associativity-- Associativity-- Distributivity-- Distributivity
Dr. Philip Cannata 22
Why Reasoning with Truth Tables is Infeasible
Works fine when there are 2 variables{T,F} {T,F} = set of potential values of variables2 2 lines in truth table
Three variables — starts to get tedious{T,F} {T,F} {T,F} = set of potential values2 2 2 lines in truth table
Twenty variables — definitely out of hand2 2 … 2 lines (220)You want to look at a million lines?If you did, how would you avoid making errors?
Hundreds of variables — not in a million years
A need for Predicate Logic. We’ll look at this with Prolog.
Dr. Philip Cannata 23
Haskell and SQL
Dr. Philip Cannata 24
Standard Oracle scott/tiger emp dept database
Dr. Philip Cannata 25
emp = [ (7839, "KING", "PRESIDENT", 0, "17-NOV-81", 5000, 10), (7698, "BLAKE", "MANAGER", 7839, "01-MAY-81", 2850, 30), (7782, "CLARK", "MANAGER", 7839, "09-JUN-81", 2450, 10), (7566, "JONES", "MANAGER", 7839, "02-APR-81", 2975, 20), (7788, "SCOTT", "ANALYST", 7566, "09-DEC-82", 3000, 20), (7902, "FORD", "ANALYST", 7566, "03-DEC-81", 3000, 20), (7369, "SMITH", "CLERK", 7902, "17-DEC-80", 800, 20), (7499, "ALLEN", "SALESMAN", 7698, "20-FEB-81", 1600, 30), (7521, "WARD", "SALESMAN", 7698, "22-FEB-81", 1250, 30), (7654, "MARTIN", "SALESMAN", 7698, "28-SEP-81", 1250, 30), (7844, "TURNER", "SALESMAN", 7698, "08-SEP-81", 1500, 30), (7876, "ADAMS", "CLERK", 7788, "12-JAN-83", 1100, 20), (7900, "JAMES", "CLERK", 7698, "03-DEC-81", 950, 30), (7934, "MILLER", "CLERK", 7782, "23-JAN-82", 1300, 10) ]
dept = [ (10, "ACCOUNTING", "NEW YORK"), (20, "RESEARCH", "DALLAS"), (30, "SALES", "CHICAGO"), (40, "OPERATIONS", "BOSTON") ]
Standard Oracle scott/tiger emp dept database in Haskell
Dr. Philip Cannata 26
Main>Main> [(empno, ename, job, sal, deptno) | (empno, ename, job, _, _, sal, deptno) <- emp]
[(7839,"KING","PRESIDENT",5000,10),(7698,"BLAKE","MANAGER",2850,30),(7782,"CLARK","MANAGER",2450,10),(7566,"JONES","MANAGER",2975,20),(7788,"SCOTT","ANALYST",3000,20),(7902,"FORD","ANALYST",3000,20),(7369,"SMITH","CLERK",800,20),(7499,"ALLEN","SALESMAN",1600,30),(7521,"WARD","SALESMAN",1250,30),(7654,"MARTIN","SALESMAN",1250,30),(7844,"TURNER","SALESMAN",1500,30),(7876,"ADAMS","CLERK",1100,20),(7900,"JAMES","CLERK",950,30),(7934,"MILLER","CLERK",1300,10)]Main>
Dr. Philip Cannata 27
Main> [(empno, ename, job, sal, deptno) | (empno, ename, job, _, _, sal, deptno) <- emp, deptno == 10]
[(7839,"KING","PRESIDENT",5000,10),(7782,"CLARK","MANAGER",2450,10),(7934,"MILLER","CLERK",1300,10)]Main>
Dr. Philip Cannata 28
Main> [(empno, ename, job, sal, dname) | (empno, ename, job, _, _, sal, edeptno) <- emp, (deptno, dname, loc) <- dept, edeptno == deptno ]
[(7839,"KING","PRESIDENT",5000,"ACCOUNTING"),(7698,"BLAKE","MANAGER",2850,"SALES"),(7782,"CLARK","MANAGER",2450,"ACCOUNTING"),(7566,"JONES","MANAGER",2975,"RESEARCH"),(7788,"SCOTT","ANALYST",3000,"RESEARCH"),(7902,"FORD","ANALYST",3000,"RESEARCH"),(7369,"SMITH","CLERK",800,"RESEARCH"),(7499,"ALLEN","SALESMAN",1600,"SALES"),(7521,"WARD","SALESMAN",1250,"SALES"),(7654,"MARTIN","SALESMAN",1250,"SALES"),(7844,"TURNER","SALESMAN",1500,"SALES"),(7876,"ADAMS","CLERK",1100,"RESEARCH"),(7900,"JAMES","CLERK",950,"SALES"),(7934,"MILLER","CLERK",1300,"ACCOUNTING")]Main>
Dr. Philip Cannata 29
Main> length [sal | (_, _, _, _, _, sal, _) <- emp]
14Main>
Main> (\y -> fromIntegral(sum y) / fromIntegral(length y)) ([sal | (_, _, _, _, _, sal, _) <- emp])
2073.21428571429Main>
Dr. Philip Cannata 30
Main> map sqrt (map fromIntegral [sal | (_, _, _, _, _, sal, _) <- emp])
[70.7106781186548,53.3853912601566,49.4974746830583,54.5435605731786,54.7722557505166,54.7722557505166,28.2842712474619,40.0,35.3553390593274,35.3553390593274,38.7298334620742,33.166247903554,30.8220700148449,36.0555127546399]Main>
Dr. Philip Cannata 31
Main> (map sqrt . map fromIntegral) [sal | (_, _, _, _, _, sal, _) <- emp]
[70.7106781186548,53.3853912601566,49.4974746830583,54.5435605731786,54.7722557505166,54.7722557505166,28.2842712474619,40.0,35.3553390593274,35.3553390593274,38.7298334620742,33.166247903554,30.8220700148449,36.0555127546399]Main>
Dr. Philip Cannata 32
Main> zip ([name | (_, name, _, _, _, _, _) <- emp]) (map sqrt (map fromIntegral [sal | (_, _, _, _, _, sal, _) <- emp]))
[("KING",70.7106781186548),("BLAKE",53.3853912601566),("CLARK",49.4974746830583),("JONES",54.5435605731786),("SCOTT",54.7722557505166),("FORD",54.7722557505166),("SMITH",28.2842712474619),("ALLEN",40.0),("WARD",35.3553390593274),("MARTIN",35.3553390593274),("TURNER",38.7298334620742),("ADAMS",33.166247903554),("JAMES",30.8220700148449),("MILLER",36.0555127546399)]Main>
Dr. Philip Cannata 33
Main> [(name, sal, dept) | (_, name, _, _, _, sal, dept) <- emp, dept `elem` [20, 30]]
[("BLAKE",2850,30),("JONES",2975,20),("SCOTT",3000,20),("FORD",3000,20),("SMITH",800,20),("ALLEN",1600,30),("WARD",1250,30),("MARTIN",1250,30),("TURNER",1500,30),("ADAMS",1100,20),("JAMES",950,30)]Main>
Dr. Philip Cannata 34
Main> [(name, sal, dept) | (_, name, _, _, _, sal, dept) <- emp, dept `notElem` [20, 30]]
[("KING",5000,10),("CLARK",2450,10),("MILLER",1300,10)]Main>
Dr. Philip Cannata 35
Main> [(name, sal, dept) | (_, name, _, _, _, sal, dept) <- emp, dept `notElem` [20, 30]] ++ [(name, sal, dept) | (_, name, _, _, _, sal, dept) <- emp, dept `elem` [20, 30]]
[("KING",5000,10),("CLARK",2450,10),("MILLER",1300,10),("BLAKE",2850,30),("JONES",2975,20),("SCOTT",3000,20),("FORD",3000,20),("SMITH",800,20),("ALLEN",1600,30),("WARD",1250,30),("MARTIN",1250,30),("TURNER",1500,30),("ADAMS",1100,20),("JAMES",950,30)]Main>
Dr. Philip Cannata 36