© M. Winter COSC 4P41 – Functional Programming 7.17.1 Abstract data types (ADTs) An ADT is a data type together with some functions to manipulate elements.

Slides:



Advertisements
Similar presentations
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  ML lists are immutable.  Elements.
Advertisements

Kathleen Fisher cs242 Reading: “A history of Haskell: Being lazy with class”,A history of Haskell: Being lazy with class Section 6.4 and Section 7 “Monads.
C O N T E X T - F R E E LANGUAGES ( use a grammar to describe a language) 1.
© M. Winter COSC 4P41 – Functional Programming Testing vs Proving Testing –uses a set of “typical” examples, –symbolic testing, –may find errors,
0 PROGRAMMING IN HASKELL Chapter 10 - Declaring Types and Classes.
String is a synonym for the type [Char].
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 14 Functional Programming It is better to.
1 Pass Compiler 1. 1.Introduction 1.1 Types of compilers 2.Stages of 1 Pass Compiler 2.1 Lexical analysis 2.2. syntactical analyzer 2.3. Code generation.
What is a Parser? A parser is a program that analyses a piece of text to determine its syntactic structure  3 means 23+4.
Using Types Slides thanks to Mark Jones. 2 Expressions Have Types: The type of an expression tells you what kind of value you might expect to see if you.
Introducing Monads Lecture 3, Designing and Using Combinators John Hughes.
0 PROGRAMMING IN HASKELL Chapter 6 - Recursive Functions Most of this should be review for you.
ISBN Chapter 4 Lexical and Syntax Analysis The Parsing Problem Recursive-Descent Parsing.
Type Inference: CIS Seminar, 11/3/2009 Type inference: Inside the Type Checker. A presentation by: Daniel Tuck.
Using Types Slides thanks to Mark Jones. 2 Expressions Have Types: The type of an expression tells you what kind of value you might expect to see if you.
Data Structures 1- Course Syllabus. 2- Introduction about Data Structures.
C o n f i d e n t i a l Developed By Nitendra NextHome Subject Name: Data Structure Using C Title: Overview of Data Structure.
0 PROGRAMMING IN HASKELL Typeclasses and higher order functions Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and.
© M. Winter COSC 4P41 – Functional Programming Enumerated types data Temp = Cold | Hot data Season= Spring | Summer | Autumn | Winter weather ::
Tuples and Lists Lecture 3, Programmeringsteknik del A.
PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
Interpretation Environments and Evaluation. CS 354 Spring Translation Stages Lexical analysis (scanning) Parsing –Recognizing –Building parse tree.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell: Types and Classes Dr. Hyunyoung Lee.
Functional Programming With examples in F#. Pure Functional Programming Functional programming involves evaluating expressions rather than executing commands.
Functional Programming guest lecture by Tim Sheard Parsing in Haskell Defining Parsing Combinators.
0 PROGRAMMING IN HASKELL Chapter 9 - Higher-Order Functions, Functional Parsers.
Advanced Programming Andrew Black and Tim Sheard Lecture 11 Parsing Combinators.
Com Functional Programming Regular Expressions and Abstract Data Types Marian Gheorghe Lecture 14 Module homepage Mole &
A Second Look At ML 1. Outline Patterns Local variable definitions A sorting example 2.
Overview of the Haskell 98 Programming Language
Topic 1 Object Oriented Programming. 1-2 Objectives To review the concepts and terminology of object-oriented programming To discuss some features of.
© M. Winter COSC 4P41 – Functional Programming Programming with actions Why is I/O an issue? I/O is a kind of side-effect. Example: Suppose there.
1 Linked-list, stack and queue. 2 Outline Abstract Data Type (ADT)‏ Linked list Stack Queue.
© M. Winter COSC 4P41 – Functional Programming Modules in Haskell Using modules to structure a large program has a number of advantages: Parts of.
Muhammad Idrees, Lecturer University of Lahore 1 Top-Down Parsing Top down parsing can be viewed as an attempt to find a leftmost derivation for an input.
Com Functional Programming Lexical Analysis Marian Gheorghe Lecture 15 Module homepage Mole & ©University of Sheffieldcom2010.
Do-it-yourself dictionaries in Haskell1 Ingmar Brouns & Lukas Spee.
Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:
Workshop: Towards Highly Portable Software Jakarta, 21 – 23 January 2003 Diselenggarakan oleh Universitas IndonesiaUniversitas Indonesia Part 1 : Programming.
Copyright Curt Hill The Assignment Operator and Statement The Most Common Statement you will use.
Programming Language Concepts (CIS 635) Elsa L Gunter 4303 GITC NJIT,
More Data Types CSCE 314 Spring CSCE 314 – Programming Studio Defining New Data Types Three ways to define types: 1.type – Define a synonym for.
Stacks This presentation shows – how to implement the stack – how it can be used in real applications.
Functional Programming Lecture 3 - Lists Muffy Calder.
Defining Classes Modules and ADTs CSCE 314 Spring 2016.
LECTURE 5 Scanning. SYNTAX ANALYSIS We know from our previous lectures that the process of verifying the syntax of the program is performed in two stages:
An introduction to functional programming using Haskell CENG242 –Recitation 1.
1 Vectors, binary search, and sorting. 2 We know about lists O(n) time to get the n-th item. Consecutive cons cell are not necessarily consecutive in.
0 PROGRAMMING IN HASKELL Typeclasses and higher order functions Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and.
© M. Winter COSC 4P41 – Functional Programming Some functions id :: a -> a id x = x const :: a -> b -> a const k _ = k ($) :: (a -> b) -> a -> b.
Polymorphic Functions
What is a Parser? A parser is a program that analyses a piece of text to determine its syntactic structure  3 means 23+4.
Announcements Today: the Parsing Domain-specific Language
String is a synonym for the type [Char].
Haskell Chapter 2.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Tree A tree is a data structure in which each node is comprised of some data as well as node pointers to child nodes
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Introduction to Data Structure
CSCE 314: Programming Languages Dr. Dylan Shell
6.001 SICP Interpretation Parts of an interpreter
Testing vs Proving Testing uses a set of “typical” examples,
CSCE 314: Programming Languages Dr. Dylan Shell
Lecture 5 Scanning.
PROGRAMMING IN HASKELL
Presentation transcript:

© M. Winter COSC 4P41 – Functional Programming Abstract data types (ADTs) An ADT is a data type together with some functions to manipulate elements of this data type. It usually consists of 1.a signature (interface), between the user and the implementor, 2.an implementation which is (completely) hidden to the user. Example: A calculator for numerical expressions. data Expr = Lit Int | IVar Var | Let Var Expr Expr | Expr :+: Expr | Expr :-: Expr | Expr :*: Expr | Expr :\: Expr

© M. Winter COSC 4P41 – Functional Programming ADTs (cont’d) eval :: Expr -> Store -> Int eval (Lit n) store = n eval (IVar v) store = value store v eval (Let v e1 e2) store = eval e2 (update store v (eval e1 store)) eval (e1 :+: e2) store = eval e1 store + eval e2 store eval (e1 :-: e2) store = eval e1 store - eval e2 store eval (e1 :*: e2) store = eval e1 store * eval e2 store eval (e1 :\: e2) store = eval e1 store `div` eval e2 store execute :: Expr -> Int execute e = eval e initial

© M. Winter COSC 4P41 – Functional Programming ADT Store The interface of Store consists of the functions / values 1.initial 2.value 3.update The implementation is hidden and can be exchanged. initial :: Store value :: Store -> Var -> Int update :: Store -> Var -> Int -> Store USER IMPLEMENTOR

© M. Winter COSC 4P41 – Functional Programming ADT Store (1 st implementation) module Store(Store,initial,value,update) where newtype Store = Sto [(Var,Int)] initial :: Store initial = Sto [] value :: Store -> Var -> Int value (Sto []) v = 0 value (Sto ((v',n):sto)) v | v == v' = n | otherwise = value (Sto sto) v update :: Store -> Var -> Int -> Store update (Sto sto) v n = Sto ((v,n):sto)

© M. Winter COSC 4P41 – Functional Programming ADT Store (2 nd implementation) module Store(Store,initial,value,update) where newtype Store = Sto (Var -> Int) initial :: Store initial = Sto (\v -> 0) value :: Store -> Var -> Int value (Sto sto) v = sto v update :: Store -> Var -> Int -> Store update (Sto sto) v n = Sto (\w -> if v==w then n else sto w)

© M. Winter COSC 4P41 – Functional Programming Type classes We can declare ADTs as belonging to particular type classes. instance Eq Store where (Sto sto1) == (Sto sto2) = sto1==sto2 instance Show Store where show (Sto sto) = show sto Note, that once declared, these instances cannot be hidden, so that even though they are not named in the export list, the functions over Store which are defined by means of these instance declarations will be available whenever the module Store is imported.

© M. Winter COSC 4P41 – Functional Programming ADT Queue The interface for the ADT Queue : type Queue a emptyQ :: Queue a isEmptyQ :: Queue a - > Bool addQ :: a -> Queue a -> Queue a remQ :: Queue a -> (a, Queue a) USER IMPLEMENTOR

© M. Winter COSC 4P41 – Functional Programming ADT Queue (1 st implementation) module Queue(Queue,emptyQ,isEmptyQ,addQ,remQ) where newtype Queue a = Qu [a] emptyQ :: Queue a emptyQ = Qu [] isEmptyQ :: Queue a -> Bool isEmptyQ (Qu xs) = null xs addQ :: a -> Queue a -> Queue a addQ x (Qu xs) = Qu (xs++[x]) remQ :: Queue a -> (a, Queue a) remQ xs) | not (isEmptyQ q)= (head xs, Qu (tail xs)) | otherwise= error ”remQ”

© M. Winter COSC 4P41 – Functional Programming Properties of the implementation One characteristic of this implementation is addQ is ‘expensive’, remQ is ‘cheap’. Alternative: addQ x (Qu xs) = Qu (x:xs) remQ xs) | not (isEmptyQ q)= (last xs, Qu (init xs)) | otherwise= error ”remQ” But now we have: addQ is ‘cheap’, remQ is ‘expensive’.

© M. Winter COSC 4P41 – Functional Programming ADT Queue (2 nd implementation) module Queue(Queue,emptyQ,isEmptyQ,addQ,remQ) where data Queue a = Qu [a] [a] emptyQ :: Queue a emptyQ = Qu [] [] isEmptyQ :: Queue a -> Bool isEmptyQ (Qu [] []) = True isEmptyQ _ = False addQ :: a -> Queue a -> Queue a addQ x (Qu xs ys) = Qu xs (x:ys) remQ :: Queue a -> (a, Queue a) remQ (Qu (x:xs) ys)= (x, Qu xs ys) remQ (Qu [] (y:ys))= remQ (Qu (reverse (y:ys)) []) remQ (Qu [] [])= error ”remQ”

© M. Winter COSC 4P41 – Functional Programming Why is there no lengthQ function? Consider the following implementation of the function lengthQ computing the length of a queue: lengthQ :: Queue a -> Int lengthQ q | isEmpty q= 0 | otherwise= 1 + (lengthQ. snd. remQ) q The definition of lengthQ is independent of the implementation, and so would not have to be reimplemented if the implementation of the type Queue a is changed. This is a good reason for leaving lengthQ out of the signature.

© M. Winter COSC 4P41 – Functional Programming Further examples of ADTs the type Tree a of binary trees whose elements are of type a, binary search trees as an extension of binary trees whose elements are ordered, the type of sets, the type of relations between a and b, the type of a graph with node from a (special case of a relation).

© M. Winter COSC 4P41 – Functional Programming Parsing Consider again the following data type for expressions: data Expr = Lit Int | IVar Var | Let Var Expr Expr | Expr :+: Expr | Expr :-: Expr | Expr :*: Expr | Expr :\: Expr The class Read can be used to generate elements of type Expr given a string representation. Notice, that the derived read function would accept strings as ”Lit 4 :\: Lit 2” rather than the natural representation ”4 \ 2”.

© M. Winter COSC 4P41 – Functional Programming A type for parsers First attempt: type Parse1 a b = [a] -> b Suppose that bracket and number are parsers of this type which recognize brackets and numbers: bracket ”(xyz”  ‘(‘ number ”234”  2 or 23 or 234 bracket ”234”  no result? Second attempt: type Parse2 a b = [a] -> [b] bracket ”(xyz”  [‘(‘] number ”234”  [2,23,234] bracket ”234”  []

© M. Winter COSC 4P41 – Functional Programming A type for parsers (cont’d) Final attempt: type Parse a b = [a] -> [(b,[a])] bracket ”(xyz”  [(‘(‘,”xyz”)] number ”234”  [(2,”34”),(23,”4”),(234,””)] bracket ”234”  []

© M. Winter COSC 4P41 – Functional Programming Some basic parsers none :: Parse a b none inp = [] succeed :: b -> Parse a b succeed val inp = [(val,inp)] token :: Eq a => a -> Parse a a token t (x:xs) | t==x = [(t,xs)] | otherwise = [] token t [] = [] spot :: (a -> Bool) -> Parse a a spot p (x:xs) | p x = [(x,xs)] | otherwise = [] spot p [] = []

© M. Winter COSC 4P41 – Functional Programming Some basic parsers (cont’d) Some examples: bracket :: Parse Char Char bracket = token ‘(‘ bracket ”(xyz”  [(‘(‘,”xyz”)] dig :: Parse Char Char dig = spot isDigit dig ”23df”  [(‘2‘,”3df”)]

© M. Winter COSC 4P41 – Functional Programming Combining Parsers alt p1 p2 recognizes anything recognized by p1 or by p2. alt :: Parse a b -> Parse a b -> Parse a b alt p1 p2 inp = p1 inp ++ p2 inp (bracket `alt` dig) ”234” Apply one parser then the second to the result(s) of the first. infixr 5 >*> (>*>) :: Parse a b -> Parse a c -> Parse a (b,c) (>*>) p1 p2 inp = [((y,z),rem2) | (y,rem1) <- p1 inp, (z,rem2) <- p2 rem1 ] (bracket >*> dig) ”(234”  [((‘(‘,‘2‘),”34”)]

© M. Winter COSC 4P41 – Functional Programming Combining Parsers (cont’d) Transform the results of the parses according to the function. build :: Parse a b -> (b -> c) -> Parse a c build p f inp = [ (f x,rem) | (x,rem) <- p inp ] (dig `build` char2int) ”23df”  [(2,”3df”)] infixr 5.*> (.*>) :: Parse a b -> Parse a c -> Parse a c p1.*> p2 = (p1 >*> p2) `build` snd infixr 5 >*. (>*.) :: Parse a b -> Parse a c -> Parse a b p1 >*. p2 = (p1 >*> p2) `build` fst

© M. Winter COSC 4P41 – Functional Programming Combining Parsers (cont’d) Recognize a list of objects. list :: Parse a b -> Parse a [b] list p = (succeed []) `alt` ((p >*> list p) `build` convert) where convert = uncurry (:) list dig ”234(”  [(””,”234(”),(”2”,”34(”),(”23”,”4(”),(”234”,”(”)] stringToken :: String -> Parse Char String stringToken s1 s2 = [ (a,b) | (a,b) <- lex s2, a==s1]

© M. Winter COSC 4P41 – Functional Programming Parsing expressions Grammar for expressions: Expr = Int | Char | let Char = Expr in Expr | (Expr + Expr) | (Expr - Expr) | (Expr * Expr) | (Expr div Expr) Example: (4 + 3) div 2

© M. Winter COSC 4P41 – Functional Programming Parsing expressions parseVar = spot (\x -> 'a' <= x && x <= 'z') parser = (reads `build` Lit) `alt`(parseVar `build` IVar) `alt`((stringToken "let".*> parseVar >*> stringToken "=".*> parser >*> stringToken "in".*> parser) `build` (\(v,(e1,e2)) -> Let v e1 e2)) `alt`((stringToken "(".*> parser >*> stringToken "+".*> parser >*. stringToken ")") `build` (uncurry (:+:))) `alt`((stringToken "(".*> parser >*> stringToken "-".*> parser >*. stringToken ")") `build` (uncurry (:-:))) `alt`((stringToken "(".*> parser >*> stringToken "*".*> parser >*. stringToken ")") `build` (uncurry (:*:))) `alt`((stringToken "(".*> parser >*> stringToken "div".*> parser >*. stringToken ")") `build` (uncurry (:\:)))

© M. Winter COSC 4P41 – Functional Programming Parsing expression (cont’d) parse str = if null p then error ”Parse error: no parse” else if snd e /= ”” then error ”Parse error: unexpected end of input” else fst e where p = parser str e = head p instance Read Expr where readsPrec n = parser

© M. Winter COSC 4P41 – Functional Programming Further considerations Alternative grammar for expressions: Expr = Int | Char | let Char = Expr in Expr | (Expr) | Expr + Expr | Expr - Expr | Expr * Expr | Expr div Expr A similar translation into a Haskell program does not work !!! Reason: the grammar above is left-recursive.

© M. Winter COSC 4P41 – Functional Programming Further considerations (cont’d) Solution: Modify grammar as follows: Expr = Expr1 | Expr1 + Expr | Expr1 - Expr | Expr1 * Expr | Expr1 div Expr Expr1 = Int | Char | let Char = Expr in Expr | (Expr)

© M. Winter COSC 4P41 – Functional Programming Using Parsec parser = do { n <- read2Parsec; -- function in Basics.hs return $ Lit n } … do { strings “(”;-- function in Bascics.hs -- Parsec only defines -- string :: String ->... t1 <- parser; spaces; strings “-”; t2 <- parser; spaces; strings “)”; return $ t1 :-: t2 }