Watch out for the arrows. Recollecting Haskell, Part V. A start on higher types: Mapping, 1. A start on higher types: Mapping, 2.

Similar documents
CSCE 314 Programming Languages

Shell CSCE 314 TAMU. Higher Order Functions

EDAF40. 2nd June :00-19:00. WRITE ONLY ON ONE SIDE OF THE PAPER - the exams will be scanned in and only the front/ odd pages will be read.

Standard prelude. Appendix A. A.1 Classes

Informatics 1 Functional Programming Lecture 7. Map, filter, fold. Don Sannella University of Edinburgh

Functional Programming TDA 452, DIT 142

Higher Order Functions in Haskell

CSc 372. Comparative Programming Languages. 11 : Haskell Higher-Order Functions. Department of Computer Science University of Arizona

CSc 520 Principles of Programming Languages. Currying Revisited... Currying Revisited. 16: Haskell Higher-Order Functions

Functional Programming TDA 452, DIT 142

Shell CSCE 314 TAMU. Functions continued

Lecture 4: Higher Order Functions

Lecture 10 September 11, 2017

INTRODUCTION TO HASKELL

CS 457/557: Functional Languages

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

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

A tour of the Haskell Prelude

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

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

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

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

CS 340 Spring 2019 Midterm Exam

HIGHER-ORDER FUNCTIONS

Lecture 2: List algorithms using recursion and list comprehensions

Exercises on ML. Programming Languages. Chanseok Oh

(ii) Define a function ulh that takes a list xs, and pairs each element with all other elements in xs.

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

A general introduction to Functional Programming using Haskell

CSci 4223 Principles of Programming Languages

2. (18 points) Suppose that the following definitions are made (same as in Question 1):

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

CSE 130 [Winter 2014] Programming Languages

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

INTRODUCTION TO FUNCTIONAL PROGRAMMING

Logic - CM0845 Introduction to Haskell

A Sudoku Solver (1A) Richard Bird Implementation. Young Won Lim 11/15/16

Introduction to Functional Programming using Haskell

Haskell Refresher Informatics 2D

Introduction to Programming: Lecture 6

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

CSCE 314 Programming Languages

What s in Main. Tobias Nipkow. December 5, Abstract

CSCE 314 Programming Languages

CSE341 Autumn 2017, Midterm Examination October 30, 2017

2. (18 points) Suppose that the following definitions are made (same as in Question 1):

Write: evens. evens [] ====> [] evens [1;2;3;4] ====> [2;4]

CITS3211 FUNCTIONAL PROGRAMMING. 6. Folding operators

CSCI-GA Final Exam

Programming Languages 3. Definition and Proof by Induction

Higher-Order Functions

Exercise 1 ( = 24 points)

Programming Language Concepts: Lecture 14

Efficient Mergesort. Christian Sternagel. August 28, 2014

Defining Functions. CSc 372. Comparative Programming Languages. 5 : Haskell Function Definitions. Department of Computer Science University of Arizona

CSE399: Advanced Programming. Handout 2

Advanced Programming Handout 7. Monads and Friends (SOE Chapter 18)

CIS 252 Introduction to Computer Science Section M013: Exam 2 (Green) March 29, Points Possible

CS 320: Concepts of Programming Languages

Programming Languages. Tail Recursion. CSE 130: Winter Lecture 8: NOT TR. last thing function does is a recursive call

Haskell 101. (Version 1 (July 18, 2012)) Juan Pedro Villa Isaza

Practical Haskell. An introduction to functional programming. July 21, Practical Haskell. Juan Pedro Villa-Isaza. Introduction.

Haskell through HUGS THE BASICS

CSE 130 [Winter 2014] Programming Languages

CSc 372 Comparative Programming Languages

Lecture 21: Functional Programming in Python. List Comprehensions

Introduction to OCaml

A Third Look At ML. Chapter Nine Modern Programming Languages, 2nd ed. 1

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

Haskell An Introduction

Programming in Haskell Aug-Nov 2015

CS115 - Module 9 - filter, map, and friends

Lecture 19: Functions, Types and Data Structures in Haskell

301AA - Advanced Programming

Shell CSCE 314 TAMU. Haskell Functions

Functional Programming - 2. Higher Order Functions

Recursion. Q: What does this evaluate to? Q: What does this evaluate to? CSE 130 : Programming Languages. Higher-Order Functions

Programming Languages

CS 440: Programming Languages and Translators, Spring 2019 Mon

CSE 3302 Programming Languages Lecture 8: Functional Programming

INFOB3TC Solutions for the Exam

Advanced Programming Handout 3

Review. Advanced Programming Handout 3. Review. Review. Review. Trees. What are the types of these functions? How about these? f1 x y = [x] : [y]

Topic 5: Higher Order Functions

Topic 5: Higher Order Functions

Informatics 1 Functional Programming Lectures 13 and 14 Monday 11 and Tuesday 12 November Type Classes. Don Sannella University of Edinburgh

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

More fun with recursion

Introduction to Functional Programming in Haskell 1 / 56

Background Operators (1E) Young Won Lim 7/7/18

CITS3211 FUNCTIONAL PROGRAMMING. 7. Lazy evaluation and infinite lists

Carlos Varela RPI September 19, Adapted with permission from: Seif Haridi KTH Peter Van Roy UCL

General Computer Science (CH ) Fall 2016 SML Tutorial: Practice Problems

CS Lecture 6: Map and Fold. Prof. Clarkson Spring Today s music: Selections from the soundtrack to 2001: A Space Odyssey

Type-indexed functions in Generic Haskell

Box-and-arrow Diagrams

Lambda expressions, functions and binding

CS 209 Functional Programming

CSE341 Spring 2017, Midterm Examination April 28, 2017

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

Transcription:

Watch out for the arrows Recollecting Haskell, Part V Higher Types CIS 352/Spring 2018 Programming Languages January 30, 2018 1 / 28 2 / 28 A start on higher types: Mapping, 1 Mapping via list comprehension doubleall :: [Int] -> [Int] doubleall lst = [ 2*x x <- lst ] addpairs :: [(Int,Int)] -> [[Int]] addpairs mns = [[m+n] (m,n) <- mns ] multall :: Int -> [Int] -> [Int] multall x ys = [ x*y y <- ys ] More generally for any function f :: a -> b, we can define a function apply_f :: [a] -> [b] apply_f xs = [f x x <- xs] A start on higher types: Mapping, 2 Mapping via structural recursion over lists doubleall :: [Int] -> [Int] doubleall [] = [] doubleall (x:xs) = (2*x):doubleAll xs addpairs :: [(Int,Int)] -> [[Int]] addpairs [] = [] addpairs ((m,n):mns) = [m+n]:addpairs mns multall :: Int -> [Int] -> [Int] multall x [] = [] multall x (y:ys) = (x*y):(multall x ys) More generally for any function f :: a -> b, we can define a function apply_f :: [a] -> [b] apply_f [] = [] apply_f (x:xs) = (f x):apply_f xs 3 / 28 4 / 28

A start on higher types: Mapping, 3 A start on higher types: Filtering, 1 Mapping via map Let us define a generic function to do mapping: map :: (a -> b) -> [a] -> [b] map f lst = [ f x x <- lst ] or map :: (a -> b) -> [a] -> [b] map f [] = [] map f (x:xs) = (f x):map f xs map is higher order, it accepts a function as an argument. E.g., map fst [(1,False), (3,True), (-5,False), (34,False)] [1,3,-5,34] map length [[1,5,6], [3,5], [], [3..10]] [3,2,0,8] map sum [[1,5,6], [3,5], [], [3..10]] [12,8,0,52] Filtering elements from a list via list comprehensions lessthan10 :: [Int] -> [Int] lessthan10 xs = [ x x <- xs, x<10 ] offdiagonal :: [(Int,Int)] -> [(Int,Int)] offdiagonal mns = [(m,n) (m,n) <- mns, m/=n] 5 / 28 6 / 28 A start on higher types: Filtering, 2 Here is a generic way of doing filtering: filter :: (a -> Bool) -> [a] -> [a] filter p lst = [x x <- lst, p x] or filter :: (a -> Bool) -> [a] -> [a] filter p [] = [] filter p (x:xs) p x = x:(filter p xs) otherwise = filter p xs So isoffdiag :: (Int,Int) -> Bool isoffdiag (m,n) = (m/=n) filter isoffdiag [(3,4),(5,5),(10,-2),(99,99)] [(3,4),(10,-2)] filter isdigit "a37bz9?" "379?" filter not [True,False,False,True] [False,False] Functions as First-Class Values In functional languages (generally), functions are first-class values, i.e. are treated just like any other value. So functions can be passed as arguments to functions returned as results from functions bound to variables expressed without being given a name (λ-expressions) elements of list (and other data structures)... A function that (i) accepts functions as arguments or (ii) returns a function as a value or (iii) both (i) and (ii) is higher order. E.g., map and filter. 7 / 28 8 / 28

Higher-type goodies, 1 dropwhile, takewhile :: (a -> Bool) -> [a] -> [a] dropwhile p [] = [] dropwhile p (x:xs) p x = dropwhile p xs otherwise = x:xs takewhile p [] = [] takewhile p (x:xs) p x = x : takewhile p xs otherwise = [] For example: Q: What is (<10) doing? Q: What is. doing?? takewhile (<10) [0,3..20] [0,3,6,9] dropwhile (<10) [0,3..20] [12,15,18] dropwhile isspace " hi there " "hi there " takewhile (not. isspace) "hi there " "hi" dropwhile (not. isspace) "hi there " " there " 9 / 28 Digression: Sections and the composition operator Sections 10 + 3 (+) 10 3 (10 +) 3 (+ 3) 10 10 == 3 (==) 10 3 (10 ==) 3 (== 3) 10 10 div 3 div 10 3 (10 div ) 3 ( div 3) 10 (.) :: (b -> c) -> (a -> b) -> a -> c (f. g) x = f (g x) Example: Define a function trim that deletes leading and trailing white space from a string trimfront str = dropwhile isspace str trim str = reverse (trimfront (reverse (trimfront str))) -- or better yet trim = reverse. trimfront. reverse. trimfront 10 / 28 Higher-type goodies, 2 Higher-type goodies, 3 span :: (a -> Bool) -> [a] -> ([a],[a]) span p [] = ([],[]) span p xs@(x:xs ) p x = (x:ys,zs) otherwise = ([],xs) where (ys,zs) = span p xs For example: span (<10) [0,3..20] ([0,3,6,9],[12,15,18]) span isspace " hi there " (" ","hi there ") Q: What is the @ doing in span p xs@(x:xs )? zipwith :: (a -> b -> c) -> [a] -> [b] -> [c] zipwith _ [] _ = [] zipwith [] = [] zipwith f (x:xs) (y:ys) = f x y : zipwith f xs ys For example: sum $ zipwith (*) [2, 5, 3] [1.75, 3.45, 0.25] sum [3.5, 17.25, 0.75] 21.50 zipwith (\a b -> (a * 30 + 3) / b) [5,4,3,2,1] [1,2,3,4,5] [153.0,61.5,31.0,15.75,6.6] Q: What is the $ doing?? Q: What is the (\a b -> (a * 30 + 3) / b) doing? 11 / 28 12 / 28

Digression: The application operator Digression: λ-expressions ($) :: (a -> b) -> a -> b f $ x = f x -- $ has low, right-associative binding precedence So sum $ filter (> 10) $ map (*2) [2..10] sum (filter (> 10) (map (*2) [2..10])) The following definitions are equivalent munge, munge :: Int -> Int munge x = 3*x+1 munge = \x -> 3*x+1 So the following expressions are equivalent map munge [2..8] map munge [2..8] map (\x -> 3*x+1) [2..8] So, (\x -> 3*x+1) defines a nameless function. We can use (\ -> ) to return functional results. E.g., addnum :: Int -> (Int->Int) addnum n = \x->(x+n) 13 / 28 14 / 28 Higher-types, structural recursion on lists, 1 Consider some structural recursion on lists: sum [] = 0 sum (x:xs) = x + sum xs concat [] = [] concat (xs:xss) = xs ++ concat xss -- = (+) x (sum xs) -- = (++) xs (concat xxs) unzip [] = ([],[]) -- = f (x,y) (unzip xys) unzip ((x,y):xys) = (x:xs,y:ys) -- where f (a,b) (as,bs) where (xs,ys) = unzip xys -- = (a:as,b:bs) These all have the general form: somefun [] = z somefun (x:xs) = f x (somefun xs) So we can encapsulate this by: foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) Higher-types, structural recursion on lists, 2 foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) Original sum [] = 0 sum (x:xs) = x + sum xs concat [] = [] concat (xs:xss) = xs ++ concat xss unzip [] = ([],[]) unzip ((x,y):xys) = (x:xs,y:ys) where (xs,ys) = unzip xys As a foldr sum xs = foldr (+) 0 xs concat xss = foldr (++) [] xss unzip xys = foldr f ([],[]) xys where f (x,y) (xs,ys) = (x:xs,y:ys) 15 / 28 16 / 28

Higher-types, structural recursion on lists, 3 foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) Higher-types, structural recursion on lists, 4 foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) 17 / 28 18 / 28 Foldr s cousin s Foldr s cousin s: alternatively, 1 For folds: look here For scans: look here 19 / 28 20 / 28

2018-01-30 Higher types Foldr s cousin s: alternatively, 1 Foldr s cousin s: alternatively, 1 Foldr s cousin s: alternatively, 2 Try: foldr1 max [1,4,8,4,9,4] foldl1 max [1,4,8,4,9,4] scanr1 max [1,4,8,4,9,4] scanl1 max [1,4,8,4,9,4] scanl1 (+) [1..5] [1,3,6,10,15] scanr1 (+) [1..5] [15,14,12,9,5] 21 / 28 2018-01-30 Higher types Foldr s cousin s: alternatively, 2 Foldr s cousin s: alternatively, 2 scanl1 (+) [1..5] [1,3,6,10,15] scanr1 (+) [1..5] [15,14,12,9,5] Class Exercises For folds: http://hackage.haskell.org/package/base-4.10.1.0/docs/prelude.html#g:11 For scans: http://hackage.haskell.org/package/base-4.10.1.0/docs/prelude.html#g:16 1. Use foldr to define n 1 2 + 2 2 + 3 2 + + n 2. 2. Use foldr and foldl to define length. 3. Use foldr and foldl to define and and or. 4. Use foldr or foldl to define reverse. 5. Use scanr or scanl to define n [1!, 2!, 3!,..., n!]. 22 / 28

2018-01-30 Higher types Class Exercises sumsq n = foldr (\ x r -> x*x+r) 0 [1..n] length1 xs = foldr (\ x r -> 1+r) 0 xs length2 xs = foldl (\ r x -> 1+r) 0 xs and1 bs = foldr (\ x r -> x && r) True bs and2 bs = foldl (\ r x -> x && r) True bs or1 bs = foldr (\ x r -> x r) False bs or2 bs = foldl (\ r x -> x r) False bs reverse xs = foldl (flip(:)) [] xs facts n = scanl (*) 1 [2..n] Class Exercises 1. Use foldr to define n 1 2 + 2 2 + 3 2 + + n 2. 2. Use foldr and foldl to define length. 3. Use foldr and foldl to define and and or. 4. Use foldr or foldl to define reverse. 5. Use scanr or scanl to define n [1!, 2!, 3!,..., n!]. Aside: Structural Recursions on Natural Numbers, 1 We can introduce a natural number data type by: data Nat = Zero Succ Nat where Zero stands for 0 and Succ stands for the function x x + 1. A structural recursion over Nat s is a function of the form: fun :: Nat -> a fun Zero = z fun (Succ n) = f (fun n) where z::a and f::a -> a. So if you expand things out, you see that fun (Succ (Succ (... Zero))) k many Succ s We can define a fold for Nat s by: foldn :: (a->a) -> a -> Nat -> a foldn f z Zero = z foldn f z (Succ n) = f (foldn f z n) = (f (f (... z))) k many f s 23 / 28 Aside: Structural Recursions on Natural Numbers, 2 Functions and types Using data Nat = Zero Succ Nat foldn :: (a->a) -> a -> Nat -> a foldn f z Zero = z foldn f z (Succ n) = f (foldn f z n) we can bootstrap arithmetic by: add m n = foldn Succ n m times m n = foldn ( add n) Zero m etc. In Haskell every function takes exactly one argument and returns exactly one value. For example: f :: Examples: Int -> Bool arg type result type (Int -> Bool) -> Char In general: g :: t1 arg type Int -> (Bool -> Char) Int -> Bool -> Char -> associates to the right -> t2 t 1 t 2 t n t t 1 (t 2... (t n t)... ) result type 24 / 28 25 / 28

Associations Convention: -> associates to the right t 1 t 2 t 3 t n t t 1 (t 2 (t 3 (... (t n t)... ))) Convention: application associates to the left Suppose f x 1 x 2 x 3... x n (... (((f x 1 ) x 2 ) x 3 )... x n ) f :: t1 -> t2 -> t3 -> t e1 :: t1 e2 :: t2 e3 :: t3 WHY? Then f e1 :: t2 -> t3 -> t f e1 e2 :: t3 -> t f e1 e2 e3 :: t Currying and Uncurrying Consider comp1 :: Int -> Int -> Bool comp1 x y = (x<y) comp2 :: (Int,Int) -> Bool comp2 (x,y) = (x<y) In fact Every f :: t1 -> t2 ->... -> tn -> t has a corresponding f :: (t1,t2,...,tn) -> t and vise versa. curry2 :: ((a,b)->c) -> a -> b -> c curry2 g = \ x y -> g(x,y) uncurry2 :: (a->b->c) -> (a,b) -> c uncurry2 f = \ (x,y) -> f x y Mathematically: This is just a fancier version of: (c b ) a = c a b from High School math. 26 / 28 27 / 28 Was that so bad? 28 / 28