dr. philip cannata 1 programming languages haskell

36
Dr. Philip Cannata Programming Languages Haskell

Upload: melvin-farmer

Post on 17-Jan-2018

226 views

Category:

Documents


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

Page 1: Dr. Philip Cannata 1 Programming Languages Haskell

Dr. Philip Cannata 1

Programming Languages

Haskell

Page 2: 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

Page 3: Dr. Philip Cannata 1 Programming Languages 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

Page 4: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 5: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 6: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 7: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 8: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 9: Dr. Philip Cannata 1 Programming Languages Haskell

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)

Page 10: Dr. Philip Cannata 1 Programming Languages Haskell

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)

Page 11: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 12: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 13: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 14: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 15: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 16: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 17: Dr. Philip Cannata 1 Programming Languages Haskell

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 )

Page 18: Dr. Philip Cannata 1 Programming Languages Haskell

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) )

Page 19: Dr. Philip Cannata 1 Programming Languages Haskell

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) )

Page 20: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 21: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 22: Dr. Philip Cannata 1 Programming Languages Haskell

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.

Page 23: Dr. Philip Cannata 1 Programming Languages Haskell

Dr. Philip Cannata 23

Haskell and SQL

Page 24: Dr. Philip Cannata 1 Programming Languages Haskell

Dr. Philip Cannata 24

Standard Oracle scott/tiger emp dept database

Page 25: Dr. Philip Cannata 1 Programming Languages Haskell

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

Page 26: Dr. Philip Cannata 1 Programming Languages 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>

Page 27: Dr. Philip Cannata 1 Programming Languages Haskell

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>

Page 28: Dr. Philip Cannata 1 Programming Languages Haskell

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>

Page 29: Dr. Philip Cannata 1 Programming Languages Haskell

Dr. Philip Cannata 29

Main> length [sal | (_, _, _, _, _, sal, _) <- emp]

14Main>

Main> (\y -> fromIntegral(sum y) / fromIntegral(length y)) ([sal | (_, _, _, _, _, sal, _) <- emp])

2073.21428571429Main>

Page 30: Dr. Philip Cannata 1 Programming Languages Haskell

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>

Page 31: Dr. Philip Cannata 1 Programming Languages Haskell

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>

Page 32: Dr. Philip Cannata 1 Programming Languages Haskell

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>

Page 33: Dr. Philip Cannata 1 Programming Languages Haskell

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>

Page 34: Dr. Philip Cannata 1 Programming Languages Haskell

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>

Page 35: Dr. Philip Cannata 1 Programming Languages Haskell

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>

Page 36: Dr. Philip Cannata 1 Programming Languages Haskell

Dr. Philip Cannata 36