Dr. Philip Cannata 1 Programming Languages Haskell.

Post on 17-Jan-2018

225 views 0 download

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 hugs

Transcript of Dr. Philip Cannata 1 Programming Languages Haskell.

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