CS510AP Quick Check Monads. QuickCheck Quick check is a Haskell library for doing random testing. You can read more about quickcheck at –http://www.math.chalmers.se/~rjmh/QuickCheck/

Slides:



Advertisements
Similar presentations
Modern Programming Languages, 2nd ed.
Advertisements

ML Lists.1 Standard ML Lists. ML Lists.2 Lists A list is a finite sequence of elements. [3,5,9] ["a", "list" ] [] Elements may appear more than once [3,4]
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  Elements may appear more than once.
Chapter 1 Object-Oriented Concepts. A class consists of variables called fields together with functions called methods that act on those fields.
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.
Programming Languages and Paradigms
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.
Control-Flow Graphs & Dataflow Analysis CS153: Compilers Greg Morrisett.
Chapter 3 DATA: TYPES, CLASSES, AND OBJECTS. Chapter 3 Data Abstraction Abstract data types allow you to work with data without concern for how the data.
Functional Programming Universitatea Politehnica Bucuresti Adina Magda Florea
Recursive Data Types Koen Lindström Claessen. Modelling Arithmetic Expressions Imagine a program to help school-children learn arithmetic, which presents.
Grab Bag of Interesting Stuff. Topics Higher kinded types Files and handles IOError Arrays.
Monads. A monad orders actions An action is any computation that has a natural notion of order. I.e. one thing happens before another. – IO is the action.
Chapter 3 Simple Graphics. Side Effects and Haskell  All the programs we have seen so far have no “side-effects.” That is, programs are executed only.
A Lightning Tour of Haskell Lecture 1, Designing and Using Combinators John Hughes.
Chapter 3 Data Abstraction: The Walls. © 2005 Pearson Addison-Wesley. All rights reserved3-2 Abstract Data Types Modularity –Keeps the complexity of a.
Test Data Generators Lecture 5. Why Distinguish Instructions? Functions always give the same result for the same arguments Instructions can behave differently.
© 2006 Pearson Addison-Wesley. All rights reserved4-1 Chapter 4 Data Abstraction: The Walls.
Advanced Programming Handout 12 Higher-Order Types (SOE Chapter 18)
Cse536 Functional Programming 1 6/24/2015 Lecture #4, Oct 6, 2004 Reading Assignments –Begin Reading chapter 3 (Simple Graphics) of the Text Homework Assignment.
Two Case Studies: QuickCheck and Wash/CGI Lecture 4, Designing and Using Combinators John Hughes.
Engineering H192 - Computer Programming The Ohio State University Gateway Engineering Education Coalition Lect 6P. 1Winter Quarter I/O in C Lecture 6.
0 PROGRAMMING IN HASKELL Chapter 9 - Interactive Programs.
Programming Paradigms Imperative programming Functional programming Logic programming Event-driven programming Object-oriented programming A programming.
Programming Languages
CMPSC 16 Problem Solving with Computers I Spring 2014 Instructor: Lucas Bang Lecture 15: Linked data structures.
PrasadCS7761 Haskell Data Types/ADT/Modules Type/Class Hierarchy Lazy Functional Language.
© Copyright 1992–2005 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. Tutorial 5 – Dental Payment Application: Introducing.
WXGE6103 Software Engineering Process and Practice Formal Specification.
CS321 Functional Programming 2 © JAS Type Checking Polymorphism in Haskell is implicit. ie the system can derive the types of all objects. This.
1 C++ Syntax and Semantics, and the Program Development Process.
Interpretation Environments and Evaluation. CS 354 Spring Translation Stages Lexical analysis (scanning) Parsing –Recognizing –Building parse tree.
Copyright 2004 Scott/Jones Publishing Alternate Version of STARTING OUT WITH C++ 4 th Edition Chapter 7 Structured Data and Classes.
Functional Programming With examples in F#. Pure Functional Programming Functional programming involves evaluating expressions rather than executing commands.
Advanced Functional Programming Tim Sheard 1 Lecture 6 Functional Programming Tim Sheard & Mark Jones Monads & Interpreters.
Testing and Debugging (Depuração em Haskell) Complementa as seções anteriores Original autorizado por: John Hughes Adaptado.
A Second Look At ML 1. Outline Patterns Local variable definitions A sorting example 2.
C++ Programming Basic Learning Prepared By The Smartpath Information systems
© 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.
0 Odds and Ends in Haskell: Folding, I/O, and Functors Adapted from material by Miran Lipovaca.
Arvind Computer Science and Artificial Intelligence Laboratory M.I.T. L13-1 October 26, 2006http:// Monadic Programming October.
Structures and Classes Version 1.0. Topics Structures Classes Writing Structures & Classes Member Functions Class Diagrams.
OOP using C Abstract data types How to accomplish the task??? Requirements Details Input, output, process Specify each task in terms of input.
1 CS 457/557: Functional Languages Lists and Algebraic Datatypes Mark P Jones Portland State University.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Interactive Programs: I/O and Monads Dr. Hyunyoung Lee.
1 Compiler Construction (CS-636) Muhammad Bilal Bashir UIIT, Rawalpindi.
Grab Bag of Interesting Stuff. Higher Order types Type constructors are higher order since they take types as input and return types as output. Some type.
Chapter SevenModern Programming Languages1 A Second Look At ML.
FUNCTIONAL PROGRAMING AT WORK - HASKELL AND DOMAIN SPECIFIC LANGUAGES Dr. John Peterson Western State Colorado University.
72 4/11/98 CSE 143 Abstract Data Types [Sections , ]
24-Jun-16 Haskell Dealing with impurity. Purity Haskell is a “pure” functional programming language Functions have no side effects Input/output is a side.
Test Data Generators. Why Distinguish Instructions? Functions always give the same result for the same arguments Instructions can behave differently on.
Chapter 12 Classes and Abstraction
Types CSCE 314 Spring 2016.
Koen Lindström Claessen
PROGRAMMING IN HASKELL
CS 326 Programming Languages, Concepts and Implementation
Agenda Warmup AP Exam Review: Litvin A2
Test Data Generators.
I/O in C Lecture 6 Winter Quarter Engineering H192 Winter 2005
Haskell Dealing with impurity 30-Nov-18.
Functional Programming
Haskell Dealing with impurity 8-Apr-19.
PROGRAMMING IN HASKELL
Grab Bag of Interesting Stuff
Programming Languages
Haskell Dealing with impurity 29-May-19.
Haskell Dealing with impurity 28-Jun-19.
Advanced Functional Programming
Presentation transcript:

CS510AP Quick Check Monads

QuickCheck Quick check is a Haskell library for doing random testing. You can read more about quickcheck at –

Overview Programmers define properties they would like to be true about there programs Programmers use default or user defined random test data generators The QuickCheck framework tests the properties against a large number of random inputs It reports the success and failure QuickCheck is in some sense orthogonal to the kind of testing done in HUnit.

Simple case prop_bad xs = (reverse xs) == xs where types = xs::[Int] Main> quickCheck prop_bad Falsifiable, after 7 tests: [0,4,-6,-2]

A useful case prop_RevId xs = reverse (reverse xs) == xs where types = xs::[Int] Main> quickCheck prop_RevId OK, passed 100 tests.

Quantified tests ==> prop_RevLong xs = length xs > 2 ==> reverse (reverse xs) == xs where types = xs::[Int] Main> quickCheck prop_RevLong OK, passed 100 tests.

But prop_RevLong xs = length xs > 4 ==> reverse (reverse xs) == xs where types = xs::[Int] Main> quickCheck prop_RevLong Arguments exhausted after 0 tests.

Collecting data collect $ prop_RevLong3 xs = length xs > 2 ==> collect (length xs) $ reverse (reverse xs) == xs where types = xs::[Int] Main> quickCheck prop_RevLong3 OK, passed 100 tests. 27% 3. 10% 5. 8% 6. 6% 9. 5% 7. 5% 4. 5% 10. 4% 8. 4% 16. 4% 11. 3% 17. 3% 14. 2% 24. 2% 13. 2% 12. 1% 44. 1% 40. 1% 36. 1% 31. 1% 28. 1% 27. 1% 26. 1% 21. 1% 18. 1% 15.

Another quantified test ordered [] = True ordered [x] = True ordered (x:y:zs) = (x <= y) && (ordered (y:zs)) insert x [] = [x] insert x (y:ys) = if x<=y then x:y:ys else y:(insert x ys) prop_Insert x xs = ordered xs ==> ordered (insert x xs) where types = x::Int Main> quickCheck prop_Insert OK, passed 100 tests.

A short side-trip Monads Monads & Actions A Monad is an Abstract Data Type (ADT) A Monad encapsulates effects –i.e. hides their implementation A Monad uses types to separates Actions from pure computations A Monad controls the order of effects

Actions It is sometimes useful to use actions or side effects in a functional program. –Update a piece of state (assignment) –do some IO –draw graphics on a display –return an exception rather than an answer –generate random test cases How do we do this? –We use a Monad –A Monad is a type constructor which has an implied action. –For example: IO Int is an action which performs some IO and then returns an Int

A monad is an ADT A monad is an abstract datatype –It abstracts computations with effects. –It hides the details of its implementation. –It exports an abstract interface. –It specifies the order in which effects occur. –It separates pure computations from effectfull ones using the type system. –It can have multiple implementations.

Monads Encapsulate Effects A monad captures the meaning and use of computations which have effects on the real world. A monad describes or specifies the effects in a “purely functional” way. A monad allows one to reason about effects, using the simple rule of substitution of equals for equals. A monad needn’t be implemented this way

A Monad uses types to separate Actions (with effects) from pure computations A Monad is a type constructor which has an implied action. For example: –a computation with type (IO Int ) –an action which might perform some IO and which then returns an Int Computations with non-monadic types cannot have any effects. They are pure computations. The user (and the compiler) can rely on this.

A monad orders effects A Monad specifies which effects come before others. The Do operator provides this control over the order in which computations occur do { var <- location x -- the first action ; write var (b+1) -- the next action }

Typing the Do do { var <- location x ; write var (b+1) ; return (b+1) } Each action must have a monadic type: (M a) If a variable is bound, it has type a, and its scope is to the end of the do The very last action cannot have a binding

A monad’s interface hides details A monad has an interface that hides the details of its implementation Every monad has at least the two operations –Do Lets users control the order of actions –Return : a -> Action a makes an empty action Each monad has its own additional operations.

An Example: IO actions Each function performs an action of doing some IO –? :t getChar -- get 1 char from stdin –getChar :: IO Char –? :t putChar -- put Char to stdout –putChar :: Char -> IO() –? :t getLine -- get a whole line from stdin –getLine :: IO String –? :t readFile -- read a file into a String –readFile :: FilePath -> IO String –? :t writeFile -- write a String to a file –writeFile :: FilePath -> String -> IO ()

Io operations getCharX :: Io Char -- get 1 char from stdin getCharX = Io(\ (c:cs) -> (c,cs,"")) putCharX :: Char -> Io() -- put Char to stdout putCharX c = Io(\ s -> ((),s,[c])) getLineX :: Io String -- get a whole line from stdin getLineX = do { c <- getCharX ; if c == '\n' then return "" else do { cs <- getLineX ; return (c:cs) } }

Example: Combining IO actions getLineX :: Io [Char] getLineX = do { c <- getCharX -- get a char ; if c == '\n' -- if its newline then return "" -- no-op action which -- returns empty string -- recursively else do { l <- getLine' -- get a line ; return (c:l) -- no-op action } -- to cons c to l } Potentially reads a string from stdin, if it is ever performed

Observations Actions are first class. –They can be abstracted (param’s of functions) –Stored in data structures. -- It is possible to have a list of actions, etc. Actions can be composed. –They can be built out of smaller actions by glueing them together with do and return –They are sequenced with do much like one uses semi-colon in languages like Pascal and C. Actions can be performed (run). –separation of construction from performance is key to their versatility. Actions of type: Action () are like statements in imperative languages. –They are used only for their side effects.

Back to Defining Generators choose :: Random a => (a,a) -> Gen a oneof :: [Gen a] -> Gen a list:: Gen [Int] list = do { elem <- choose (1,100) ; tail <- list ; oneof [ return [], return(elem:tail) ] }

Note: Gen is a Monad Gen is a Monad A program with type (Gen a) produces an object of type ‘a’ while performing a possible ‘Gen’ action, generating random bits of data.

Generating Ordered lists orderedList:: Int -> Gen [Int] orderedList n = do { elem <- choose (1,n) ; tail <- orderedList elem ; oneof [ return [], return(elem:tail) ] }

Controlling choice frequency :: [(Int,Gen a)] -> Gen a list2:: Gen [Int] list2 = do { elem <- choose (1,100) ; tail <- list ; frequency [ (1,return []), (4,return(elem:tail)) ] }

using Monads better lift :: Monad m => (b -> c) -> m b -> m c lift f x = do { a <- x; return(f a)} lift2 :: Monad m => (b -> c -> d) -> m b -> m c -> m d lift2 f x y = do { a <- x; b <- y; return(f a b)}

Another list generator list3:: Gen [Int] list3 = frequency [ (1,return []), (4,lift2 (:) (choose (1,100)) list3) ]

Generating Random RE data RE = Empty | Union RE RE | Concat RE RE | Star RE | C Char

re:: Gen RE re = frequency [ (1,return Empty), (6,lift C (choose ('a','z'))), (3,lift2 Union re re), (3,lift2 Concat re re), (1,lift Star re) ]

Using generators forAll $ \ -> prop_re = forAll re $ \ re -> all (reAsPred re) (reAsSet re)

Controlling the test generation re2:: Int -> Int -> Gen RE re2 star 0 = frequency [(1,return Empty),(3,lift C (choose ('a','z')))] re2 star d = frequency [ (3,return Empty), (8,lift C (choose ('a','z'))), (4,lift2 Union (re2 star (d-1)) (re2 star (d-1))), (4,lift2 Concat (re2 star (d-1)) (re2 star (d-1))), (star,lift Star (re2 0 (d-1))) ]

The sized function Test generation is controlled by the library. Test sizes start out small, and increase in size as the number of tests increase. Users can control this with the function sized. sized :: (Int -> Gen a) -> Gen a

Using sized re3:: Int -> Int -> Gen RE re3 star 0 = frequency [(1,return Empty),(3,lift C (choose ('a','z')))] re3 star d = frequency [ (3,return Empty), (8,lift C (choose ('a','z'))), (4,lift2 Union (re3 star (d `div` 2)) (re3 star (d`div` 2))), (4,lift2 Concat (re3 star (d`div` 2)) (re3 star (d`div` 2))), (star,lift Star (re3 0 (d`div` 2))) ] prop_re3 = forAll (sized (re3 1)) $ \ r -> all (reAsPred r) (reAsSet r)

Installing default generators class Arbitrary a where arbitrary :: Gen a coarbitrary :: a -> Gen b -> Gen b instance Arbitrary RE where arbitrary = sized (re3 1)