CS 209 Functional Programming

Similar documents
Parsing. Zhenjiang Hu. May 31, June 7, June 14, All Right Reserved. National Institute of Informatics

CS 440: Programming Languages and Translators, Spring 2019 Mon

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

Higher Order Functions in Haskell

CSCE 314 Programming Languages

CSCE 314 Programming Languages. Functional Parsers

Recursive Definitions, Fixed Points and the Combinator

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

CSCE 314 Programming Languages. Monadic Parsing

EECS 700 Functional Programming

Standard prelude. Appendix A. A.1 Classes

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Functional Parsers

Programming Languages Fall 2013

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

It is better to have 100 functions operate one one data structure, than 10 functions on 10 data structures. A. Perlis

CSCE 314 Programming Languages. Monadic Parsing

Exercise 1 ( = 24 points)

Haskell Overview II (2A) Young Won Lim 8/9/16

CSC312 Principles of Programming Languages : Functional Programming Language. Copyright 2006 The McGraw-Hill Companies, Inc.

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Introduction to Haskell

An introduction introduction to functional functional programming programming using usin Haskell

The List Datatype. CSc 372. Comparative Programming Languages. 6 : Haskell Lists. Department of Computer Science University of Arizona

Lecture 19: Functions, Types and Data Structures in Haskell

Functional Programming

INTRODUCTION TO HASKELL

CS 11 Haskell track: lecture 1

Exercise 1 ( = 18 points)

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Functions

CSE 3302 Programming Languages Lecture 8: Functional Programming

Informatics 1 Functional Programming Lectures 15 and 16. IO and Monads. Don Sannella University of Edinburgh

Functional Programming. Overview. Topics. Definition n-th Fibonacci Number. Graph

CS 320: Concepts of Programming Languages

Overview. A normal-order language. Strictness. Recursion. Infinite data structures. Direct denotational semantics. Transition semantics

Haskell Overview II (2A) Young Won Lim 8/23/16

CS 457/557: Functional Languages

Haskell & functional programming, some slightly more advanced stuff. Matteo Pradella

CSc 372 Comparative Programming Languages

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

Shell CSCE 314 TAMU. Functions continued

CSc 372. Comparative Programming Languages. 8 : Haskell Function Examples. Department of Computer Science University of Arizona

Functional Logic Programming Language Curry

301AA - Advanced Programming

Lecture 5: Lazy Evaluation and Infinite Data Structures

Lecture 4: Higher Order Functions

Introduction to Programming, Aug-Dec 2006

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Recursion and Induction: Haskell; Primitive Data Types; Writing Function Definitions

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Basics

Haskell Types, Classes, and Functions, Currying, and Polymorphism

Structural polymorphism in Generic Haskell

Lecture 2: List algorithms using recursion and list comprehensions

CSCE 314 Programming Languages

CS 360: Programming Languages Lecture 12: More Haskell

Programming Languages 3. Definition and Proof by Induction

Functional Programming for Logicians - Lecture 1

Exercise 1 ( = 22 points)

Advanced Functional Programming

1.3. Conditional expressions To express case distinctions like

According to Larry Wall (designer of PERL): a language by geniuses! for geniuses. Lecture 7: Haskell. Haskell 98. Haskell (cont) - Type-safe!

Monads seen so far: IO vs Gen

Type-indexed functions in Generic Haskell

Informatics 1 Functional Programming 19 Tuesday 23 November IO and Monads. Philip Wadler University of Edinburgh

CS 320: Concepts of Programming Languages

Functional Programming in C++

Typed Scheme: Scheme with Static Types

Programming Language Concepts: Lecture 14

Functional Programming - 2. Higher Order Functions

Haskell An Introduction

Functional Programming Mid-term exam Tuesday 3/10/2017

CS 457/557: Functional Languages

Advanced Topics in Programming Languages Lecture 2 - Introduction to Haskell

A general introduction to Functional Programming using Haskell

Haskell: From Basic to Advanced. Part 2 Type Classes, Laziness, IO, Modules

Week 5 Tutorial Structural Induction

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages. Lambda calculus

Programming Language Concepts, CS2104 Lecture 7

Monadic Parsing. 1 Chapter 13 in the book Programming in Haskell (2nd ed.) by. 2 Chapters 10 and 16 in the book Real World Haskell by Bryan

Introduction. chapter Functions

Logical Methods in... using Haskell Getting Started

CIS552: Advanced Programming

Shell CSCE 314 TAMU. Haskell Functions

Introduction to Programming: Lecture 3

This example highlights the difference between imperative and functional programming. The imperative programming solution is based on an accumulator

Topic 5: Higher Order Functions

Topic 5: Higher Order Functions

301AA - Advanced Programming [AP-2017]

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

Haskell 5.1 INTERACTIVE SESSIONS AND THE RUN-TIME SYSTEM

Functional Programming. Overview. Topics. Recall λ-terms. Examples

Advanced features of Functional Programming (Haskell)

Principles of Programming Languages

Haskell through HUGS THE BASICS

Overloading, Type Classes, and Algebraic Datatypes

Advanced Type System Features Tom Schrijvers. Leuven Haskell User Group

CSCE 314 Programming Languages

CS 340 Spring 2019 Midterm Exam

Functional Programming and Haskell

3. Functional Programming. Oscar Nierstrasz

Functional Programming TDA 452, DIT 142

Transcription:

CS 209 Functional Programming Lecture 03 - Intro to Monads Dr. Greg Lavender Department of Computer Science Stanford University "The most important thing in a programming language is the name. A language will not succeed without a good name. I have recently invented a very good name and now I am looking for a suitable language. --- Professor Donald Knuth 1 But first...lambda Expressions Before we get into Monads, we first have to become more comfortable with using lambda expressions, which we say before As we have seen, a lambda expression is of the form: (\<var list> -> body) args (\x -> x + 1) 2 => 3 (\x -> x * x) 5 => 25 (\x y -> x + y) 2 3 => 5 (\x y -> x + y) 2 => (\y -> 2 + y) (\(x,y) -> x + y) (2,3) => 5 (\(x,y) -> x + y) 2 => error 2 2

Lambda expressions Lambda expressions are most often used with standard higher-order functions, such as foldl/foldr, scanl/scanr, map, etc. id = \x -> x succ = \n -> n + 1 square = \x -> x * x sum = foldl (\x y -> x + y) 0 prod = foldl (\x y -> x * y) 1 len = foldl (\x _ -> x + 1) 0 fact n = foldl (\x y -> x * y) 1 [1..n] suml :: (Num a) => [a] -> (a,int) suml = foldl (\(s,l) x -> (s+x, l+1)) (0,0) 3 Fixed Points A fixed point is a value x in the domain of a function that is the same in the co-domain f(x). Functionals may also have fixed points, i.e., a higher-order function returns its function argument as the result id x = x, for all x fact 1 = 1, fact 2 = 2 fibonacci 0 = 0, fibonacci 1 = 1 square 0 = 0, square 1 = 1 abs x = x, if x >= 0 sin 0 = 0 D x(e x ) = e x 4

A Fixed Point Operator Fix applied to any function F returns F and repeats F by applying Fix to F one more time. Fix is actually the fixed point operator commonly defined in the untyped λ-calculus called the (lazy) Y combinator. Y is also called the paradoxical combinator because it was the source of the logical paradox of the original λ-calculus Fix F = F (Fix F) Y = (λf. (λx.f(xx)) (λx.f(xx))) Y F = (λf. (λx.f(xx)) (λx.f(xx))) F! = (λx.f(xx)) (λx.f(xx)) = F ((λx.f(xx)) (λx.f(xx)))! = F (Y F) => F (F (Y F)) => F (F (F (Y F))..) =>... i.e., Y (fix) is a fixed point operator that when applied to any function F applies F to a copy of itself repeatedly (i.e., recursively) the recursion only terminates if F has an internal terminating condition, i.e., F must contain a conditional expression, so if-then-else is an important primitive in any language with recursion. See McCarthy s paper mentioned at the end of the Lecture 02 notes. 5 Fix in Haskell A fixed point operator in Haskell is a higher order function that takes a function as an argument and recurses on that function fix f = f (fix f) or fix f = let x = f x in x If we flip this equation around, we get: f (fix f) = fix f So fix f is a fixed point for any higher order function f since f (fix f) returns fix f as a result. 6

Using Fix in Haskell zeros = fix (\f -> 0:f) gcd :: Integral a => a -> a -> a gcd = fix (\f x y -> case (abs x, abs y) of (x,0) -> x (x,y) -> f y (x `rem` y)) fact :: Integer->Integer fact = fix (\f n -> if n == 0 then 1 else n * f (n-1)) fibs :: [Integer] fibs = fix (\xs -> 0 : scanl (+) 1 xs) 7 Using Fix in Haskell len :: [a] -> Int len = fix (\f xs -> case xs of [] -> 0 (x:xs) -> 1 + (f xs)) map :: (a->b) -> [a] -> [b] map = fix (\f g xs -> case xs of [] -> [] (x:xs) -> g x : f g xs) foldl :: (a -> b -> a) -> a -> [b] -> a foldl = fix (\f g z xs -> case xs of [] -> z (x:xs) -> f g (g z x) xs 8

Fix is Lazy Fix only works because of lazy evaluation. If Haskell had eager evaluation, f (fix f) would never terminate: f (fix f) => f f (fix f) => f f f (fix f) => fact = fix (\f n -> if n=0 then 1 else n*f(n-1)) fact 3 => (\f n -> if n==0 then 1 else n*f(n-1)) (fix f) 3!! => (if 3==0 then 1 else 3*(fix f)(3-1))!! => (3*((\f n -> if n==0 then 1 else n*f(n-1))(fix f)(3-1))!! =>!! => (3*(2*(1*1)))!! => 6 9 The Monad Type Class A Monad is any instance of the polymorphic Monad type class that implements the minimal operators: (>>=) and return. Think of a Monad as a container for a value that will be used in a sequence of computations. class Monad m where return :: a -> m a -- return x: instantiate an monad of a (ma) (>>=) :: m a -> (a -> m b) -> m b -- m >>= f: xform ma to mb using f (>>) :: m a -> m b -> m b -- p >> q: xform ma & mb into an mb fail :: String -> m a -- construct an failure monad of a -- Minimal complete definition: (>>=), return p >> q = p >>= \ _ -> q -- same as >>=, except function is omitted fail s = error s 10

Example: The List Monad We can use the list data type [] as the parameter m instance Monad [ ] where -- m a :: [a] (x:xs) >>= f = f x ++ (xs >>= f) -- iterate f over the entire list [] >>= f = [] return x = [x] -- construct a singleton list with x fail s = [] -- failure is just the empty list The following are all equivalent: xprod xs ys = xs >>= (\x -> ys >>= (\y -> return (x,y))) xprod xs ys = do { x <- xs; y <- ys; return (x,y) } xprod xs ys = do x <- xs -- foreach x in xs y <- ys -- foreach y in ys return (x,y) -- [(x,y)] xprod xs ys = [(x,y) x <- xs, y <- ys] 11 Do Notation Applied to Lists map f xs = [ f x x <- xs] or map f xs = do { x <- xs; return (f x) } filter p xs = [ x x <- xs, p x] or filter p xs = do { x <- xs; if (p x) then return x else [] } msort :: (Ord a) => [a] -> [a] msort [] = [] msort (p:rest) = msort left ++ [p] ++ msort right where left = do { x <- rest; if x <= p then return x else [] } -- rest >>= (\x -> if x <= p then [x] else []) right = do { x <- rest; if x > p then return x else [] } -- rest >>= (\x -> if x > p then [x] else []) 12

The Maybe Type The Maybe datatype captures the concept that a computation may return nothing or just a value of type a data Maybe a = Nothing Just a deriving (Eq, Ord, Read, Show) If you prefer, you can think of the Maybe type existentially (aka Sartre) as a computation results in being or nothingness data Existential = Nothingness Being a The maybe function in the Haskell Prelude operates on the Maybe datatype maybe :: b -> (a -> b) -> Maybe a -> b maybe n f Nothing = n maybe n f (Just x) = f x 13 The Maybe Monad The Maybe monad is useful when we are using other monads and a computation may return nothing or just a value and we need to return a monad as a result. We will see how this is used in Monadic Parsing instance Monad Maybe where Just x >>= k = k x Nothing >>= k = Nothing return x = Just x fail s = Nothing 14

The Matrix Monad Define Reality in terms of the Matrix data Reality a = Matrix a Zion a deriving (Show) instance Monad Reality where Matrix x >>= jackin = jackin x Zion x >>= phonehome = phonehome x return x = Zion x fail s = Matrix s Mr. Smith is a fixed point combinator. Neo is a supercombinator that terminates Mr. Smith :-) mrsmith f = f (mrsmith f) neo tf f = tf (mrsmith f) 15 The Either Type The Either type is similar to the Maybe type in that it allows us to have a choice of two different kinds of things. A Left thing or a Right thing. Another way to think of Either is that either a computation succeeds (Left) or it fails (Right) data Either a b = Left a Right b deriving (Eq, Ord, Read, Show) either :: (a -> c) -> (b -> c) -> Either a b -> c either l r (Left x) = l x either l r (Right y) = r y 16

Syntactic Parsing Syntactic Parsing is common computational process where we process a string of characters from left-toright and convert the characters into some other structure on which some other computation can be performed. For example: 1+2*3 is a just a string of characters that we often want to interpret as an arithmetic expression and compute a value. Before we can evaluate this string of characters, we need to syntactically parse it and convert an expression tree with binary values at the nodes and then perform a postorder evaluation to reduce the expression tree to a result value. 17 Parsing Terminology In parsing, we normally ignore whitespace unless it has syntactic significance. A string that is to be parsed is said to contain tokens. E.g, 1+2*3 has 5 tokens: 1 is a constant numeral token + is a binary operator token for addition 2 is a constant numeral token * is a binary operator token for multiplication 3 is a constant numeral token A token may consist of more than one character. E.g., This is a sequence of tokens has 6 tokens all separate by whitespace 18

A Simple Parser Data Type In Haskell, we define a polymorphic parser type and a set of building block parsing functions that can be combined/sequenced to effect the parsing of a arithmetic expression, a program, or something else. The Parser type needs to be a function type, since a parser is a function that maps a String to some other type, e.g., type Parser = String -> Tree To be more general we want to be able to parse a String into any type a, not just a Tree structure. We also want to have the flexibility to return a list of results of the parse, not just one: type Parser a = String -> [(a, String)] 19 Parsing Functions We can write a generic parse function that given a specific parser function, it applies that function to the input: parse :: Parser a -> String -> [(a, String)] parse pf input = pf input We then need a set of basic parsing functions: return :: a -> Parser return v = \inp -> [(v,inp)] failure :: Parser a failure = \inp -> [] 20

Item Parsing Function Given an input string, we can write a simple item parser that parses one character at a time from the string item :: Parser Char item = \inp -> case inp of -- note that String = [Char] [] -> [] -- empty string (x:xs) -> [(x,xs)] parse item this is a string => [( t, his a string )] 21