Overloading, Type Classes, and Algebraic Datatypes

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

What does my program mean?

Advanced features of Functional Programming (Haskell)

User-Defined Algebraic Data Types

Data Types The ML Type System

CS558 Programming Languages

Type Processing by Constraint Reasoning

CSE 3302 Programming Languages Lecture 8: Functional Programming

CS558 Programming Languages

Programming Languages Fall 2013

CSCE 314 Programming Languages

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

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

Advances in Programming Languages

Lists. Michael P. Fourman. February 2, 2010

Types and Type Inference

Types and Type Inference

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

Lecture #23: Conversion and Type Inference

Type Checking and Type Inference

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

Course year Typeclasses and their instances

Chapter 15. Functional Programming. Topics. Currying. Currying: example. Currying: example. Reduction

CSCE 314 Programming Languages

Type-indexed functions in Generic Haskell

CS 320: Concepts of Programming Languages

CS 360: Programming Languages Lecture 12: More Haskell

Programming in Haskell Aug-Nov 2015

CS 457/557: Functional Languages

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

Lecture 19: Functions, Types and Data Structures in Haskell

Haskell Overloading (1) LiU-FP2016: Lecture 8 Type Classes. Haskell Overloading (3) Haskell Overloading (2)

A general introduction to Functional Programming using Haskell

Polymorphic lambda calculus Princ. of Progr. Languages (and Extended ) The University of Birmingham. c Uday Reddy

Functional Programming in Haskell Part I : Basics

CSCI-GA Scripting Languages

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

Type system. Type theory. Haskell type system. EDAN40: Functional Programming Types and Type Classes (revisited)

Overview. Elements of Programming Languages. Another example. Consider the humble identity function

Type Systems, Type Inference, and Polymorphism

Types, Type Inference and Unification

CS558 Programming Languages

CS 11 Haskell track: lecture 1

Typed Racket: Racket with Static Types

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

Haskell 5.1 INTERACTIVE SESSIONS AND THE RUN-TIME SYSTEM

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

The Typed Racket Guide

Software System Design and Implementation

02157 Functional Programming. Michael R. Ha. Lecture 2: Functions, Types and Lists. Michael R. Hansen

CS 457/557: Functional Languages

Simple Unification-based Type Inference for GADTs

CSC324 Principles of Programming Languages

Where is ML type inference headed?

Polymorphism and Type Inference

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

FUNCTIONAL PROGRAMMING NO.9 TYPE AND CLASS. Tatsuya Hagino

Programming with Math and Logic

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

Data Structures (list, dictionary, tuples, sets, strings)

A Fourth Look At ML. Chapter Eleven Modern Programming Languages, 2nd ed. 1

Introduction to Haskell

Solution sheet 1. Introduction. Exercise 1 - Types of values. Exercise 2 - Constructors

Lecture 7: Type Systems and Symbol Tables. CS 540 George Mason University

cs242 Kathleen Fisher Reading: Concepts in Programming Languages, Chapter 6 Thanks to John Mitchell for some of these slides.

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

Haskell 98 in short! CPSC 449 Principles of Programming Languages

Datatype declarations

Functional Logic Programming Language Curry

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

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

INTRODUCTION TO HASKELL

Functional Programming and Modeling

An introduction introduction to functional functional programming programming using usin Haskell

Principles of Programming Languages

Functional programming Primer I

Overview. Declarative Languages D7012E. Overloading. Overloading Polymorphism Subtyping

Advanced Functional Programming

Tree Equality: The Problem

Overview of OOP. Dr. Zhang COSC 1436 Summer, /18/2017

Topic 9: Type Checking

Topic 9: Type Checking

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

Inductive Data Types

CS 320: Concepts of Programming Languages

COP4020 Programming Assignment 1 - Spring 2011

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

CSci 450: Org. of Programming Languages Overloading and Type Classes

Compiler Theory. (Semantic Analysis and Run-Time Environments)

Introduction to OCaml

Data types for mcrl2

INTRODUCTION TO FUNCTIONAL PROGRAMMING

Imperative languages

IA014: Advanced Functional Programming

Generic polymorphism on steroids

Standard prelude. Appendix A. A.1 Classes

Haskell Refresher Informatics 2D

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine.

Principles of Programming Languages 2017W, Functional Programming

Transcription:

Overloading, Type Classes, and Algebraic Datatypes Delivered by Michael Pellauer Arvind Computer Science and Artificial Intelligence Laboratory M.I.T. September 28, 2006 September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-1 Last Time Type Inference Rules (App) TE e 1 : τ -> τ TE e 2 : τ TE (e 1 e 2 ) : τ (Abs) TE + {x : τ} e : τ TE λx.e : τ -> τ Type Inference Algorithm Def W(TE, e) = Case e of λx.e = let (S 1, τ 1 ) = W(TE + { x : u }, e); in (S 1, S 1 (u) -> τ 1 ) (e 1 e 2 ) = let (S 1, τ 1 ) = W(TE, e 1 ); (S 2, τ 2 ) = W(S 1 (TE), e 2 ); S 3 = Unify(S 2 (τ 1 ), τ 2 -> u); in (S 3 S 2 S 1, S 3 (u)) September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-2 1

Last Time Hindley-Milner Type System Allows ForAll Generalization and Instantiation What s the type of: fst x y = x snd x y = y complicated x = fst (snd x) September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-3 Aside: Type Annotations When programming in Haskell, we could let the compiler infer all the types However this can be difficult for a human to read. Consider: c f g = \x -> g (f x) vs c :: (a -> b) -> (b -> c) -> (a -> c) c f g = \x -> g (f x) Type signatures serve as documentation and are as important as a good function name September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-4 2

Inference Algorithm with Annotations Question 1: Are annotations an assertion, or a hint? In Haskell, they are an assertion Question 2: How should the inference algorithm change? First approach: Add annotations as a constraint Second approach: Attempt to unify inferred type with given type Question 3: What happens if the user s annotation is too general? Too specific? Too general: an error Too specific: The user-given type becomes the actual type of the function September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-5 Conclusion: Type Inference Now you understand the Haskell type system! Almost The Hindley-Milner system allows for parametric polymorphism Similar to Java Generics Haskell also features a second type of polymorphism: Overloading Somewhat similar to Java virtual functions September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-6 3

Overloading ad hoc polymorphism A symbol can represent multiple values each with a different type. For example: + represents plusint :: Int -> Int -> Int plusfloat :: Float -> Float -> Float The context determines which value is denoted. The overloading of an identifier is resolved when the unique value associated with the symbol in that context can be determined. Compiler tries to resolve overloading but sometimes can't. The user must declare the type explicitly in such cases. September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-7 Overloading vs. Polymorphism Both allow a single identifier to be used for multiple types. However, the two concepts are very different: 1. A polymorphic function represents a single function that works for many types. Overloading uses the same name for several different functions. 2. All specific types of a polymorphic identifier are instances of a most general type September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-8 4

The Most General Type The most general type of twice f = \x -> f (f x) is t.(t -> t) -> (t -> t) Any type can be substituted for t to get an instance of twice: (Int -> Int) -> (Int -> Int) (String -> String) -> (String -> String) Overloaded + does not have a most general type: plusint :: Int -> Int -> Int plusfloat :: Float -> Float -> Float Has + type t. t -> t -> t? No! + makes sense for some types t, but not for all! September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-9 Handling Overloading Not a problem in explicitly typed languages: the compiler has enough context information to resolve the overloading. Not a problem in OO languages (e.g., Java) where objects carry their type at runtime, and dynamic dispatch is possible. Hard to integrate in languages that use type inference ML: ad-hoc support for limited cases (==) Haskell: real solution type classes Allows overloading of user-defined symbols September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-10 5

Type Classes Type classes group together related functions (e.g., +, -) that are overloaded over the same types (e.g., Int, Float): class Num a where (==), (/=) :: a -> a -> Bool (+), (-), (*) :: a -> a -> a negate :: a -> a... instance Num Int where x == y = integer_eq x y x + y = integer_add x y instance Num Float where... September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-11 Overloaded Constants (Num t) is read as a predicate t is an instance of class Num sqr :: (Num a) => a -> a sqr x = x * x What about constants? Consider plus1 x = x + 1 If 1 is treated as an integer then plus1 cannot be overloaded. In ph numeric literals are overloaded and considered a short hand for (frominteger the_integer_1_value) where frominteger :: (Num a) => Integer -> a September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-12 6

The Equality Operator Equality is an overloaded function, not a polymorphic one class Eq a where (==), (/=) :: a -> a -> Bool a /= b = not (a == b) Equality needs to be defined for each type of interest. Default definition for /= Smart compilers can derive the code for structural equality September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-13 Type Class Hierarchy class (Eq a) => Ord a where (<),(<=),(>=),(>) :: a -> a -> Bool max, min :: a -> a -> a Eq is a superclass of Ord: If type a is an instance of Ord, a is also an instance of Eq Ord inherits the specification of (==), (/=) from Eq September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-14 7

Read and Show Functions The raw input from a keyboard or output to the screen or file is usually a string. However, different programs interpret the string differently depending upon their type signature. A program to calculate monthly mortgage payments may assign the following signatures: read :: String -> Int - principal, duration read :: String -> Float -rate show :: Float -> String - monthly payments what is the type of read and show? read :: String -> a show :: a -> String Polymorphic? September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-15 Overloaded Read and Show Haskell has a type class Read of readable types and a type class Show of showable types read :: Read a => String -> a show :: Show a => a -> String September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-16 8

Ambiguous Overloading identity :: String -> String identity x = show (read x) What is the type of (read x)? Cannot be resolved! Many different types would do. Compiler requires type declarations in such cases. identity :: String -> String identity x = show ((read x) :: Int) September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-17 Implementation How does sqr find the correct function for *? sqr :: (Num a) => a -> a sqr x = x * x An overloaded function is compiled assuming an extra dictionary argument. sqr = \class_inst x -> (class_inst.(*)) x x Then (sqr 23) will be compiled as sqr IntClassInstance 23 Most dictionaries can be eliminated at compile time by function specialization. September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-18 9

Haskell Type Classes vs. Java Classes Similarities Group together common sets of operations Class hierarchy: super/sub-classes, inheritance Dictionaries virtual method tables (vtables) Differences The instance of a type class is a type, while the instance of a class is an object; types objects No notion of mutable state in Haskell In Java, objects carry dictionaries (vtables); in Haskell, dictionaries are separate from values (connected by the type system) September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-19 Aside: Static vs Dynamic Typing What is the type of x? let x = 5 let x = False let x = if False then 5 else False let x = if readboolfromuser() then 5 else False Haskell is a Statically typed language Types must be determinable at compilation time Scheme, Lisp are dynamically typed Values are tagged with types at runtime and dynamically checked In Haskell, one represents dynamic choice between different types with algebraic datatypes September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-20 10

Algebraic datatypes Algebraic types are tagged unions of products Example keyword data Shape = Line Pnt Pnt Triangle Pnt Pnt Pnt Quad Pnt Pnt Pnt Pnt "union" new type "products (fields) - new "constructors" (a.k.a. "tags", "disjuncts", "summands") - a k-ary constructor is applied to k type expressions September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-21 Examples of Algebraic datatypes data Bool = False True data Day = Sun Mon Tue Wed Thu Fri Sat data Maybe a = Nothing Just a data List a = Nil Cons a (List a) data Tree a = Leaf a Node (Tree a) (Tree a) data Tree a b = Leaf a Nonleaf b (Tree a b) (Tree a b) data Course = Course String Int String (List Course) name number description pre-reqs September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-22 11

Constructors are functions Constructors can be used as functions to create values of the type let l1 :: Shape l1 = Line e1 e2 in t1 :: Shape = Triangle e3 e4 e5 q1 :: Shape = Quad e6 e7 e8 e9... where each "ej" is an expression of type "Pnt" September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-23 Pattern-matching on algebraic types Pattern-matching is used to examine values of an algebraic type anchorpnt :: Shape -> Pnt anchorpnt s = case s of Line p1 p2 -> p1 Triangle p3 p4 p5 -> p3 Quad p6 p7 p8 p9 -> p6 A pattern-match has two roles: A test: "does the given value match this pattern?" Binding ("if the given value matches the pattern, bind the variables in the pattern to the corresponding parts of the value") September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-24 12

Pattern-matching scope & don t cares Each clause starts a new scope: can reuse bound variables Can use "don't cares" for bound variables anchorpnt :: Shape -> Pnt anchorpnt s = case s of Line p1 _ -> p1 Triangle p1 -> p1 Quad p1 _ -> p1 September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-25 Pattern-matching more syntax Functions can be defined directly using pattern-matching anchorpnt :: Shape -> Pnt anchorpnt (Line p1 _) = p1 anchorpnt (Triangle p1 ) = p1 anchorpnt (Quad p1 _) = p1 Pattern-matching can be used in list comprehensions (later) (Line p1 p2) <- shapes September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-26 13

Pattern-matching Type safety Given a "Line" object, it is impossible to read "the field corresponding to the third point in a Triangle object because: all unions are tagged unions fields of an algebraic type can only be examined via pattern-matching September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-27 Special syntax Function type constructor Int -> Bool Conceptually: Function Int Bool i.e., the arrow is an "infix" type constructor Tuple type constructor (Int, Bool) Conceptually: Tuple2 Int Bool Similarly for Tuple3,... September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-28 14

Type Synonyms versus data Point = Point Int Int type Point = (Int,Int) a new data type a type synonym Type Synonyms do not create new types. It is just a convenience to improve readability. move :: Point -> (Int,Int) -> Point move (Point x y) (sx,sy) = Point (x + sx) (y + sy) versus move (x,y) (sx,sy) = (x + sx, y + sy) September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-29 Abstract Types A rational number is a pair of integers but suppose we want to express it in the reduced form only. Such a restriction cannot be enforced using an algebraic type. module Rationalpackage (Rational,rational,rationalParts) where data Rational = RatCons Int Int rational :: Int -> Int -> Rational rational x y = let d = gcd x y in RatCons (x/d) (y/d) rationalparts :: Rational -> (Int,Int) rationalparts (RatCons x y)= (x,y) No pattern matching on abstract data types September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-30 15

List: A Recursive Data Type data List t = Nil Cons t (List t) A list data type can be constructed in two different ways: an empty list or a non-empty list Nil Cons x xs the first element - All elements of a list have the same type the rest of the elements - The list type is recursive and polymorphic September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-31 Infix notation Cons x xs x:xs 2:3:6:Nil 2:(3:(6:Nil)) [2,3,6] List Int [Int] This list may be visualized as follows: 2 3 6 September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-32 16

Example: Split a list data Token = Word String Number Int Split a list of tokens into two lists - a list words and a list of numbers. split :: [Token]-> ([String],[Int]) split [] = ([],[]) split (t:ts) =? let in (ws,ns) = split ts case t of Word w -> ((w:ws),ns) Number n -> (ws,(n:ns)) Next time --- list comprehensions September 28, 2006 http://www.csg.csail.mit.edu/6.827 L07-33 17