CS 440: Programming Languages and Translators, Spring 2019 Mon

Similar documents
Higher Order Functions in Haskell

CS 440: Programming Languages and Translators, Spring 2019 Mon 2/4

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

Lecture 4: Higher Order Functions

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

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

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

CS 320: Concepts of Programming Languages

CS 457/557: Functional Languages

An introduction introduction to functional functional programming programming using usin Haskell

Lecture 19: Functions, Types and Data Structures in Haskell

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

CS 209 Functional Programming

301AA - Advanced Programming

CS 11 Haskell track: lecture 1

Logic - CM0845 Introduction to Haskell

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

CS 320: Concepts of Programming Languages

CS 360: Programming Languages Lecture 10: Introduction to Haskell

CSE 3302 Programming Languages Lecture 8: Functional Programming

A general introduction to Functional Programming using Haskell

Programming Paradigms

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

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

CITS3211 FUNCTIONAL PROGRAMMING. 6. Folding operators

Algebraic Types. Chapter 14 of Thompson

Shell CSCE 314 TAMU. Haskell Functions

Functional Programming in Haskell for A level teachers

CSCE 314 Programming Languages

Standard prelude. Appendix A. A.1 Classes

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

INTRODUCTION TO HASKELL

Haskell Scripts. Yan Huang

Shared Variables and Interference

CSCE 314 Programming Languages

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

301AA - Advanced Programming [AP-2017]

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

Applicative, traversable, foldable

Topic 5: Higher Order Functions

Topic 5: Higher Order Functions

Shell CSCE 314 TAMU. Higher Order Functions

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

CSCE 314 Programming Languages

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

Haskell: Lists. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Friday, February 24, Glenn G.

Haskell Overview III (3A) Young Won Lim 10/4/16

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

Functional Programming - 2. Higher Order Functions

Applicative, traversable, foldable

Parallel Haskell on MultiCores and Clusters

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

Exercise 1 ( = 24 points)

Advanced features of Functional Programming (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

HIGHER-ORDER FUNCTIONS

Types, Expressions, and States

Tentamen Functioneel Programmeren 2001 Informatica, Universiteit Utrecht Docent: Wishnu Prasetya

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

Shared Variables and Interference

Overview. Declarative Languages D7012E. Overloading. Overloading Polymorphism Subtyping

Title: Recursion and Higher Order Functions

Haskell 98 in short! CPSC 449 Principles of Programming Languages

Typed Racket: Racket with Static Types

Functional Programming and Haskell

Introduction to Functional Programming in Haskell 1 / 56

Background Type Classes (1B) Young Won Lim 6/14/18

The Typed Racket Guide

CIS 194: Homework 4. Due Wednesday, February 18, What is a Number?

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

Programming Languages 3. Definition and Proof by Induction

Programming Language Concepts: Lecture 14

Program Calculus Calculational Programming

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

CS422 - Programming Language Design

Programming Languages Fall 2013

CITS3211 FUNCTIONAL PROGRAMMING. 7. Lazy evaluation and infinite lists

CS 457/557: Functional Languages

Monad Background (3A) Young Won Lim 10/5/17

Haskell An Introduction

Principles of Programming Languages

Background Type Classes (1B) Young Won Lim 6/28/18

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

Exercise 1 ( = 18 points)

Logical Methods in... using Haskell Getting Started

The type checker will complain that the two branches have different types, one is string and the other is int

CS 61A, Fall, 2002, Midterm #2, L. Rowe. 1. (10 points, 1 point each part) Consider the following five box-and-arrow diagrams.

Advanced Topics in Programming Languages Lecture 2 - Introduction to Haskell

Data Abstraction. An Abstraction for Inductive Data Types. Philip W. L. Fong.

Exercises on ML. Programming Languages. Chanseok Oh

Basic types and definitions. Chapter 3 of Thompson

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

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

Scheme Quick Reference

Homework 1: Functional Programming, Haskell

Lecture 5: Lazy Evaluation and Infinite Data Structures

Haskell Programs. Haskell Fundamentals. What are Types? Some Very Basic Types. Types are very important in Haskell:

6.001 Notes: Section 6.1

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

Transcription:

Haskell, Part 4 CS 440: Programming Languages and Translators, Spring 2019 Mon 2019-01-28 More Haskell Review definition by cases Chapter 6: Higher-order functions Revisit currying map, filter Unnamed ("lambda") functions; function definitions as function_name = lambda function. folding a list From Chapter 7: Making our own Types... Algebraic datatypes - enumerations, simple recursive structures, constructor patterns Review: Last time, Definition by cases List clauses of function definition; order of patterns is important: don't put vl _ =... first). vl [] = "empty" vl [ _ ] = "singleton" -- vl [x] = "singleton" ok too -- Can build lists using :, so vl ( _ : [ ]) is equivalent vl [ _, _ ] = "short" vl _ = "long" Prelude> :t vl vl :: [a] -> [Char] Prelude> vl [] "empty" Prelude> vl [1,2] "short" Prelude> vl [1,3,5,2] "long" Can have boolean guards in function definitions (boolean tests) fact n n <= 0 = 1 n > 0 = n * fact(n-1) -- order doesn't matter with non-overlapping tests v. Fri 2/1, 21:31 1 James Sasaki, 2018

Prelude> fact 5 120 Local variables in function definitions A where clause lets you calculate a local value and use it in the function vl x len == 0 = "empty" len == 1 = "short" len > 1 = "long" where len = length x Prelude> vl [] "empty" Let expressions are also okay for defining local variables vl x = let len = length x in if len == 0 then "empty" else if len == 1 then "short" else "long" Prelude> vl [1,3,5] "long" Case expressions let you take an expression and match it against various patterns vl x = case length x of 0 -> "empty" 1 -> "short" _ -> "long" Prelude> vl "string" "long" Skip Ch 5 (recursion) Ch 6 Higher order functions Recall: A higher order function is a function that takes another function as a parameter or returns a function as a result. Haskell uses curried functions: Instead of f : Int Int Int Int as in most languages in Haskell, we would have f ::: Int -> Int -> Int -> Int. v. Fri 2/1, 21:31 2 James Sasaki, 2018

Arrow is right-associative, so f :: Int -> (Int -> (Int -> Int)) is equivalent. So f 17 is a function :: that you can use like any other function. (It's a partially-applied version of f.) f :: Int -> Int -> Int -> Int f a b c = a * b + c Prelude> :t f f :: Int -> Int -> Int -> Int Prelude> f 3 5 8 23 Prelude> g = f 3 Prelude> :t g g :: Int -> Int -> Int Prelude> h = g 5 Prelude> :t h h :: Int -> Int Prelude> h 8 23 Recall we needed to give g 5 a name so that we wouldn't try to print its value (causes an error). Prelude> g 5 -- can't print a function value <interactive>:74:1: error: No instance for (Show (Int -> Int)) arising from a use of print (maybe you haven't applied a function to enough arguments?) In a stmt of an interactive GHCi command: print it When you say variable = expression, it gives the variable a value but it doesn't print the value out. Prelude> z = 5 Prelude> z -- evaluate z so I can see the value 5 Prelude> h = g 5 Prelude> -- now we have an h; if I ask for it's value, I get an error Prelude> h <interactive>:80:1: error: No instance for (Show (Int -> Int)) arising from a use of print (maybe you haven't applied a function to enough arguments?) In a stmt of an interactive GHCi command: print it v. Fri 2/1, 21:31 3 James Sasaki, 2018

More functions on lists Recall map :: (a -> b) -> [a] -> [b] a function on a values, a list of a values, returns the list of results Prelude> map sqrt [2..5] [1.4142135623730951,1.7320508075688772,2.0,2.23606797749979] Similar is filter, which takes a boolean test function (a -> Bool) and an a list and returns the values of the list that pass the test: Prelude> positive x = if x > 0 then else False Prelude> positive x = x > 0 -- is equivalent Prelude> map positive [3, 5, -1, 2, -9, 7, -2, -3] [,,False,,False,,False,False] Prelude> filter positive [3, 5, -1, 2, -9, 7, -2, -3] [3,5,2,7] Another example: find values divisible by 3 Prelude> divisible_by_3 x = mod x 3 == 0 -- using mod as a prefix function Prelude> divisible_by_3 x = x `mod` 3 == 0 -- equivalent defn, using mod as a binary operator Prelude> divisible_by_3 6 Prelude> filter divisible_by_3 [27..83] [27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81] Filter and find last value Prelude> largest_multiple_of_3 x = last (filter divisible_by_3 x) Prelude> largest_multiple_of_3 [27..83] 81 Lambda functions It can be annoying to write a function like largest_multiple_of_3 just to use it in one spot We can use unnamed functions instead. Below, \ x -> x `mod` 3 == 0 is a function that takes an x and returns true if x mod 3 is zero. Prelude> -- divisible_by_3 x = x `mod` 3 == 0 Prelude> -- divisible_by_3 = \ x -> x `mod` 3 == 0 -- same as previous line Prelude> divisible_by_3 6 Backslash is Haskell's representation of greek lowercase lambda. The actual lambda notation would be λ x. x `mod` 3 == 0. In fact, function declarations like f x = exp is short for f = \x -> exp v. Fri 2/1, 21:31 4 James Sasaki, 2018

This makes function definitions like other variable definitions like y = 3 (variable = value). Warning: If f is recursive then f = \x -> recursive expression doesn't work in the regular lambda calculus (works okay here) 1. Prelude> f a b c = a * b + c Prelude> f = \a -> \b -> \c -> a * b + c -- the function that takes a and returns a function that takes b... Prelude> f 3 5 8 23 Lambdas are useful for short things you use once. Prelude> filter positive [3, 5, -1, 2, -9, 7, -2, -3] [3,5,2,7] Prelude> filter (\x -> x > 0) [3, 5, -1, 2, -9, 7, -2, -3] [3,5,2,7] Prelude> positive x = x > 0 -- usual definition syntax Prelude> positive = \x -> x > 0 -- using lambda Folding lists Folding a list lets you combine its elements using some operation, like adding together a list of numbers. foldl takes a binary operation, a starting value, and the list to fold. Prelude> foldl (-) 0 [3,5,8] -16 For foldl, the starting value goes on the left, and the operations are done left-to-right. Prelude> (((0-3) - 5) - 8) -16 foldr goes right-to-left, with the starting value at the right end. Prelude> foldr (-) 0 [3,5,8] 6 Prelude> (3 - (5 -(8-0))) 6 The types for foldl and foldr let you fold more than just lists. The classtype Foldable is for types you can fold. Lists are built-in Foldable. If you define a datatype (see in a bit), you might be able to fold its values too. The type for foldl and foldr says Foldable t =>... t a. Foldable "types" are actually type constructors (take a type and build another type). List of... is a built-in type constructor. 1 Forgot this proviso in lecture -- we'll see later that Haskell's laziness lets f = \x ->...use of f... work recursively. v. Fri 2/1, 21:31 5 James Sasaki, 2018

Prelude> :t foldl foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b Prelude> :t foldr foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b In foldl (-) 0 [3, 5, 8], we use Int for the type variables a and b in (b -> a -> b) -> b -> t a -> b, and we use [...] (list-of) as t. So our use of foldl had type (Int -> Int -> Int) -> Int -> [Int] -> Int. (We take three arguments, one after another: A curried binary function on integers, an integer, and a list of integers, and we return an integer. The plain integer argument is the starting point for the folding (it's what gets returned if you fold []). Since + is associative, foldl and foldr will return the same result when given the same arguments: foldl (+) 0 [3,5,8] and foldr (+) 0 [3,5,8] both return 16. In lecture I said "since + is associative and commutative" but it's only associativity that matters for flipping foldl / foldr. Commutativity ensures that reordering the elements doesn't change anything: foldl (+) 0 [3, 5, 8] = foldr (+) 0, [5, 8, 3] = 16. Since - is not associative, foldl and foldr can return different values. (We saw this above.) And since - is not commutative, reordering the elements can change the result: foldl (-) 0 [1, 2] foldl (-) 0 [2, 1]. The Learn You... book has an example that uses folding to define our own elem function. (elem x y is true if x is a member of list y) With elem' y ys, the foldl function is used to search the ys for a y. For y and ys, we can use any type that supports equality testing (e.g. Int). However, the accumulated result is a boolean (it answers the question "Have we found y yet?") Prelude> elem' y ys = foldl (\acc x -> if x == y then else acc) False ys Prelude> elem' 0 [] False Prelude> elem' 3 [1,2,3,4] If y is 3 then the lambda in elem' becomes \acc x -> if x == 3 then else acc. Let's give that function a name. Prelude> f acc x = if x == 3 then else acc -- always looking for a 3. Folding left uses f to look (from left-to-right) for a 3 in the list. Prelude> False `f` 1 False Prelude> (False `f` 1 ) `f` 2 v. Fri 2/1, 21:31 6 James Sasaki, 2018

False Prelude> ((False `f` 1 ) `f` 2) `f` 3 Prelude> (((False `f` 1) `f` 2) `f` 3) `f` 4 ------------------------------ Omit flawed discussion of folding using function composition :- ( ------------------------------ Algebraic types We can define our own types like trees, etc. Simple example: Define our own enumerations Prelude> data Color = Red Blue Prelude> :info Color data Color = Red Blue! -- Defined at <interactive>:224:1 Prelude> :info Red data Color = Red...!-- Defined at <interactive>:224:14 Define a function on Colors: opposite Red = Blue opposite Blue = Red Oops -- forgot that datatypes create values that aren't automatically printable. Prelude> opposite Red <interactive>:231:1: error: No instance for (Show Color) arising from a use of print In a stmt of an interactive GHCi command: print it Oops again -- they aren't automatically testable for equality Prelude> opposite Red == Blue <interactive>:232:1: error: No instance for (Eq Color) arising from a use of == In the expression: opposite Red == Blue In an equation for it : it = opposite Red == Blue But Haskell has a very nice feature v. Fri 2/1, 21:31 7 James Sasaki, 2018

The deriving clauses ask Haskell to figure out how to test for equality and print values of type Color Prelude> data Color = Red Blue deriving (Eq, Show) Prelude> Red -- Now a color value can be printed Red opp Red = Blue opp Blue = Red Prelude> opp Red Blue Prelude> opp Red == Blue -- can test for equality Here's a simple tree type, with the Haskell-supplied == and show. (Trees where the leafs are labeled by integers.) Prelude> data IntTree = Leaf Int Node IntTree IntTree deriving (Eq, Show) Prelude> Leaf 0 == Leaf 0 Prelude> Leaf 0 == Leaf 1 False Prelude> Node (Leaf 0) (Leaf 1) -- create a tree value; it gets printed Node (Leaf 0) (Leaf 1) Prelude> t1 = Node (Leaf 0) (Leaf 1) Prelude> t2 = Node t1 t1 Prelude> t2 -- a tree with t1 and t2 as its left and right subtrees Node (Node (Leaf 0) (Leaf 1)) (Node (Leaf 0) (Leaf 1)) Datatype constructor patterns You can define functions on IntTrees using Leaf and Node (similarly to how you can use : and [] on lists) Simple recursive routine to sum the values in a tree: sumtree :: IntTree -> Int sumtree (Leaf x) = x sumtree (Node sub1 sub2) = sumtree sub1 + sumtree sub2 Prelude> sumtree (Leaf 0) 0 Prelude> t1 Node (Leaf 0) (Leaf 1) Prelude> sumtree t1 v. Fri 2/1, 21:31 8 James Sasaki, 2018

1 Prelude> t2 Node (Node (Leaf 0) (Leaf 1)) (Node (Leaf 0) (Leaf 1)) Prelude> sumtree t2 2 Prelude> v. Fri 2/1, 21:31 9 James Sasaki, 2018