1 CS 457/557: Functional Languages Lists and Algebraic Datatypes Mark P Jones Portland State University.

Slides:



Advertisements
Similar presentations
Functional Programming Lecture 10 - type checking.
Advertisements

Introduction A function is called higher-order if it takes a function as an argument or returns a function as a result. twice :: (a  a)  a  a twice.
Programming with Lists
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.
15-Jan-15 More Haskell Functions Maybe, Either, List, Set, Map.
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.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Patterns in ML functions. Formal vs. actual parameters Here's a function definition (in C): –int add (int x, int y) { return x + y; } –x and y are the.
0 LECTURE 5 LIST COMPREHENSIONS Graham Hutton University of Nottingham.
0 PROGRAMMING IN HASKELL Chapter 7 - Higher-Order Functions.
Higher-Order Functions Koen Lindström Claessen. What is a “Higher Order” Function? A function which takes another function as a parameter. Examples map.
A Lightning Tour of Haskell Lecture 1, Designing and Using Combinators John Hughes.
0 PROGRAMMING IN HASKELL Chapter 4 - Defining Functions.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Advanced Programming Handout 12 Higher-Order Types (SOE Chapter 18)
0 PROGRAMMING IN HASKELL Chapter 6 - Recursive Functions Most of this should be review for you.
Cse536 Functional Programming 1 6/28/2015 Lecture #3, Oct 4, 2004 Reading Assignments –Finish chapter 2 and begin Reading chapter 3 of the Text Today’s.
Comp 205: Comparative Programming Languages Functional Programming Languages: More Lists Recursive definitions List comprehensions Lecture notes, exercises,
CS 2104 : Prog. Lang. Concepts. Functional Programming I Lecturer : Dr. Abhik Roychoudhury School of Computing From Dr. Khoo Siau Cheng’s lecture notes.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
0 REVIEW OF HASKELL A lightening tour in 45 minutes.
0 PROGRAMMING IN HASKELL Chapter 7 - Defining Functions, List Comprehensions.
Chapter 9: Functional Programming in a Typed Language.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell: Types and Classes Dr. Hyunyoung Lee.
1-Nov-15 Haskell II Functions and patterns. Data Types Int + - * / ^ even odd Float + - * / ^ sin cos pi truncate Char ord chr isSpace isUpper … Bool.
0 PROGRAMMING IN HASKELL Chapter 9 - Higher-Order Functions, Functional Parsers.
1 Functional Programming Lecture 6 - Algebraic Data Types.
A Second Look At ML 1. Outline Patterns Local variable definitions A sorting example 2.
Overview of the Haskell 98 Programming Language
0 Odds and Ends in Haskell: Folding, I/O, and Functors Adapted from material by Miran Lipovaca.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell: Higher-order Functions Dr. Hyunyoung Lee.
0 PROGRAMMING IN HASKELL Chapter 4 - Defining Functions.
Lee CSCE 314 TAMU 1 CSCE 314 Programming Languages Haskell: More on Functions and List Comprehensions Dr. Hyunyoung Lee.
Chapter SevenModern Programming Languages1 A Second Look At ML.
0 PROGRAMMING IN HASKELL Based on lecture notes by Graham Hutton The book “Learn You a Haskell for Great Good” (and a few other sources) Odds and Ends,
Recursion Higher Order Functions CSCE 314 Spring 2016.
Haskell Chapter 5, Part II. Topics  Review/More Higher Order Functions  Lambda functions  Folds.
List Operations CSCE 314 Spring CSCE 314 – Programming Studio Tuple and List Patterns Pattern matching with wildcards for tuples fst (a, _) = a.
An introduction to functional programming using Haskell CENG242 –Recitation 1.
Lecture 16: Advanced Topic: Functional Programming CS5363 Compiler and Programming Languages.
6-Jul-16 Haskell II Functions and patterns. Data Types Int + - * / ^ even odd Float + - * / ^ sin cos pi truncate Char ord chr isSpace isUpper … Bool.
© 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.
Conditional Expressions
Principles of programming languages 12: Functional programming
Types CSCE 314 Spring 2016.
ML: a quasi-functional language with strong typing
Functions and patterns
A lightening tour in 45 minutes
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Type & Typeclass Syntax in function
PROGRAMMING IN HASKELL
Types and Classes in Haskell
CSCE 314: Programming Languages Dr. Dylan Shell
Higher Order Functions
PROGRAMMING IN HASKELL
CS 457/557: Functional Languages Folds
CSE 3302 Programming Languages
Functions and patterns
CSCE 314: Programming Languages Dr. Dylan Shell
PROGRAMMING IN HASKELL
Functions and patterns
PROGRAMMING IN HASKELL
Presentation transcript:

1 CS 457/557: Functional Languages Lists and Algebraic Datatypes Mark P Jones Portland State University

2 Why Lists? Lists are a heavily used data structure in many functional programs Special syntax is provided to make programming with lists more convenient Lists are a special case / an example of: An algebraic datatype (coming soon) A parameterized datatype (coming soon) A monad (coming, but a little later)

3 Naming Convention: We often use a simple naming convention: If a typical value in a list is called x, then a typical list of such values might be called xs (i.e., the plural of x) … and a list of lists of values called x might be called xss A simple convention, minimal clutter, and a useful mnemonic too!

4 Prelude Functions: (++):: [a] -> [a] -> [a] reverse:: [a] -> [a] take:: Int -> [a] -> [a] drop:: Int -> [a] -> [a] takeWhile:: (a -> Bool) -> [a] -> [a] dropWhile :: (a -> Bool) -> [a] -> [a] replicate:: Int -> a -> [a] iterate:: (a -> a) -> a -> [a] repeat:: a -> [a] …

5 Constructor Functions: What if you can’t find a function in the prelude that will do what you want to do? Every list takes the form: [], an empty list (x:xs), a non-empty list whose first element is x, and whose tail is xs Equivalently: the list type has two constructor functions: The constant [] :: [a] The operator (:) :: a -> [a] -> [a] Using “pattern matching”, we can also take lists apart …

6 Functions on Lists: null :: [a] -> Bool null [] = True null (x:xs) = False head :: [a] -> a head (x:xs) = x tail:: [a] -> [a] tail (x:xs)= xs

7 Recursive Functions: last:: [a] -> a last (x:[])= x last (x:y:xs)= last (y:xs) init:: [a] -> [a] init (x:[])= [] init (x:y:xs)= x : init (y:xs) map :: (a -> b) -> [a] -> [b] map f []= [] map f (x:xs) = f x : map f xs

8 … continued: inits:: [a] -> [[a]] inits []= [[]] inits (x:xs)= [] : map (x:) (inits xs) subsets:: [a] -> [[a]] subsets []= [[]] subsets (x:xs)= subsets xs ++ map (x:) (subsets xs) in List library user defined

9 Why Does This Work? What does it mean to say that [] and (:) are the constructor functions for lists? No Junk: every list value is equal either to [], or else to a list of the form (x:xs) (ignoring non-termination, for now) No Confusion: if x  y, or xs  ys, then x:xs  y:ys A pair of equations f [] = … f (x:xs)= … defines a unique function on list values

10 Algebraic Datatypes:

11 Algebraic Datatypes: Booleans and Lists are both examples of “algebraic datatypes”: No Junk: Every Boolean value can be constructed using either False or True Every list can be described using (a combination of) [] and (:) No Confusion: True  False []  (x:xs) and if (x:xs)=(y:ys), then x=y and xs=ys

12 In Haskell Notation: data Bool = False | True introduces: A type, Bool A constructor function, False :: Bool A constructor function, True :: Bool data List a = Nil | Cons a (List a) introduces A type, List t, for each type t A constructor function, Nil :: List a A constructor function, Cons :: a -> List a -> List a

13 More Enumerations: data Rainbow= Red | Orange | Yellow | Green | Blue| Indigo | Violet introduces: A type, Rainbow A constructor function, Red :: Rainbow … A constructor function, Violet :: Rainbow No Junk: Every value of type Rainbow is one of the above seven colors No Confusion: The seven colors above are distinct values of type Rainbow

14 More Recursive Types: data Shape =Circle Radius | Polygon [Point] | Transform Transform Shape data Transform = Translate Point | Rotate Angle | Compose Transform Transform introduces: Two types, Shape and Transform Circle :: Radius -> Shape Polygon :: [Point] -> Shape Transform :: Transform -> Shape -> Shape …

15 More Parameterized Types: data Maybe a = Nothing | Just a introduces: A type, Maybe t, for each type t A constructor function, Nothing :: Maybe a A constructor function, Just :: a -> Maybe a data Pair a b = Pair a b introduces A type, Pair t s, for any types t and s A constructor function Pair :: a -> b -> Pair a b

16 General Form: Algebraic datatypes are introduced by top-level definitions of the form: data T a 1 … a n = c 1 | … | c m where: T is the type name (must start with a capital letter) a 1, …, a n are (distinct) (type) arguments/parameters/ variables (must start with lower case letter) (n  0) Each of the c i is an expression F i t 1 … t k where:  t 1, …, t k are type expressions that (optionally) mention the arguments a 1, …, a n  F i is a new constructor function F i :: t 1 -> … -> t p -> T a 1 … a n  The arity of F i, k  0 Quite a lot for a single definition!

17 No Junk and Confusion: The key properties that are shared by all algebraic datatypes: No Junk: Every value of type T a 1 … a n can be written in the form F i e 1 … e k for some choice of constructor F i and (appropriately typed) arguments e 1, …, e k No Confusion: Distinct constructors or distinct arguments produce distinct results These are fundamental assumptions that we make when we write and/or reason about functional programs.

18 Pattern Matching: In addition to introducing a new type and a collection of constructor functions, each data definition also adds the ability to pattern match over values of the new type For example, given data Maybe a = Nothing | Just a then we can define functions like the following: orElse:: Maybe a -> a -> a Just x `orElse` y= x Nothing `orElse` y= y

19 Pattern Matching & Substitution: The result of a pattern match is either: A failure A success, accompanied by a substitution that provides a value for each of the values in the pattern Examples: [] does not match the pattern (x:xs) [1,2,3] matches the pattern (x:xs) with x=1 and xs=[2,3]

20 Patterns: More formally, a pattern is either: An identifier Matches any value, binds result to the identifier An underscore (a “wildcard”) Matches any value, discards the result A constructed pattern of the form C p 1 … p n, where C is a constructor of arity n and p 1, …,p n are patterns of the appropriate type Matches any value of the form C e 1 … e n, provided that each of the e i values matches the corresponding p i pattern.

21 Other Pattern Forms: For completeness: “Sugared” constructor patterns: Tuple patterns (p 1,p 2 ) List patterns [p 1, p 2, p 3 ] Strings, for example: "hi" = (‘h’ : ‘i’ : []) Labeled patterns Numeric Literals: Can be considered as constructor patterns, but the implementation uses equality (==) to test for matches “as” patterns, Lazy patterns, ~pat (n+k) patterns

22 Function Definitions: In general, a function definition is written as a list of adjacent equations of the form: f p 1 … p n = rhs where: f is the name of the function that is being defined p 1, …, p n are patterns, and rhs is an expression All equations in the definition of f must have the same number of arguments (the “arity” of f)

23 … continued: Given a function definition with m equations: f p 1,1 … p n,1 = rhs 1 f p 1,2 … p n,2 = rhs 2 … f p 1,m … p n,m = rhs m The value of f e 1 … e n is S rhs i, where i is the smallest integer such that the expressions e j match the patterns p j,i and S is the corresponding substitution.

24 Guards, Guards! A function definition may also include guards (Boolean expressions): f p 1 … p n | g 1 = rhs 1 | g 2 = rhs 2 | g 3 = rhs 3 An expression f e 1 … e n will only match an equation like this if all of the e i match the corresponding p i and, in addition, at least one of the guards g j is True In that case, the value is S rhs j, where j is the smallest index such that g j is True (The prelude defines otherwise = True :: Bool for use in guards.)

25 Where Clauses: A function definition may also a where clause: f p 1 … p n = rhs where decls Behaves like a let expression: f p 1 … p n = let decls in rhs Except that where clauses can scope across guards: f p 1 … p n | g 1 = rhs 1 | g 2 = rhs 2 | g 3 = rhs 3 where decls Variables bound here in decls can be used in any of the g i or rhs i

26 Example: filter filter:: (a -> Bool) -> [a] -> [a] filter p []= [] filter p (x:xs) | p x= x : rest | otherwise= rest where rest = filter p xs

27 Example: Binary Search Trees data Tree = Leaf | Fork Tree Int Tree insert :: Int -> Tree -> Tree insert n Leaf = Fork Leaf n Leaf insert n (Fork l m r) | n <= m = Fork (insert n l) m r | otherwise = Fork l m (insert n r) lookup :: Int -> Tree -> Bool lookup n Leaf= False lookup n (Fork l m r) | n < m = lookup n l | n > m = lookup n r | otherwise = True

28 Case Expressions: Case expressions can be used for pattern matching: case e of p 1 -> e 1 p 2 -> e 2 … p n -> e n Equivalent to: let f p 1 = e 1 f p 2 = e 2 … f p n = e n in f e

29 … continued: Guards and where clauses can also be used in case expressions: filter p xs = case xs of [] -> [] (x:xs) | p x -> x:ys | otherwise -> ys where ys = filter p xs

30 If Expressions: If expressions can be used to test Boolean values: if e then e 1 else e 2 Equivalent to: case e of True-> e 1 False-> e 2

31 Summary: Algebraic datatypes can support: Enumeration types Parameterized types Recursive types Products (composite/aggregate values); and Sums (alternatives) Type constructors, Constructor functions, Pattern matching Unifying features: No junk, no confusion!

32 Example: transpose transpose :: [[a]] -> [[a]] transpose [] = [] transpose ([] : xss) = transpose xss transpose ((x:xs) : xss) = (x : [h | (h:t) <- xss]) : transpose (xs : [ t | (h:t) <- xss]) Example: transpose [[1,2,3],[4,5,6]] = [[1,4],[2,5],[3,6]]

33 Example: say Say> putStr (say "hello") H H EEEEE L L OOO H H E L L O O HHHHH EEEEE L L O O H H E L L O O H H EEEEE LLLLL LLLLL OOO Say>

34 … continued: say= ('\n':). unlines. map (foldr1 (\xs ys->xs++" "++ys)). transpose. map picChar picChar 'A' = [" A ", " A A ", "AAAAA", "A A", "A A"] etc…

35 Composition and Reuse: Say> (putStr. concat. map say. lines. say) "A" A A A AAAAA A A A A A A AAAAA AAAAA A A A A A A A A A A A A A A A A A A A AAAAA AAAAA AAAAA AAAAA AAAAA A A A A A A A A A A A AAAAA A A A A A A AAAAA A A Say>