Type Processing by Constraint Reasoning

Similar documents
Type Processing by Constraint Reasoning

Functional dependencies versus type families and beyond

Simple Unification-based Type Inference for GADTs

Overloading, Type Classes, and Algebraic Datatypes

Advances in Programming Languages

Type Classes in Haskell Tom Schrijvers. Leuven Haskell User Group

CSC324 Principles of Programming Languages

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

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

Principles of Programming Languages

Simon Peyton Jones Microsoft Research August 2013

User-Defined Algebraic Data Types

Lambda Calculus and Type Inference

Structural polymorphism in Generic Haskell

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

Advanced features of Functional Programming (Haskell)

Confluence for Non-Full Functional Dependencies

Lambda Calculus and Type Inference

Where is ML type inference headed?

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

Katholieke Universiteit Leuven Department of Computer Science

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

CS 457/557: Functional Languages

Standard prelude. Appendix A. A.1 Classes

Types and Type Inference

Overview. Declarative Languages D7012E. Overloading. Overloading Polymorphism Subtyping

Principal Type Inference for GHC-Style Multi-Parameter Type Classes

CS 11 Haskell track: lecture 1

Types and Type Inference

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

Type Classes and Instance Chains: A Relational Approach. John Garrett Morris

Topic 9: Type Checking

Topic 9: Type Checking

Simplifying and Improving Qualified Types

Type-indexed functions in Generic Haskell

Type families and data kinds

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

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

Type Inference for Multi-Parameter Type Classes

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

Introduction to Programming, Aug-Dec 2006

Programming Languages Fall 2013

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

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

CS 360: Programming Languages Lecture 12: More Haskell

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

To What Extend Is Type Inference for Parameteric Polymorphism Possible in the Presence of Ad-Hoc and Subtype Polymorphism

Extended Static Checking for Haskell (ESC/Haskell)

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.

Type Systems, Type Inference, and Polymorphism

Lecture 19: Functions, Types and Data Structures in Haskell

An introduction introduction to functional functional programming programming using usin Haskell

CSCI-GA Scripting Languages

A general introduction to Functional Programming using Haskell

CS 457/557: Functional Languages

Lecture 2: List algorithms using recursion and list comprehensions

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

Lecture #23: Conversion and Type Inference

Haskell An Introduction

Arbitrary-rank polymorphism in (GHC) Haskell

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

Higher Order Functions in Haskell

301AA - Advanced Programming [AP-2017]

Polymorphism Overview (1A) Young Won Lim 2/20/18

Functional Logic Overloading

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

CS 320: Concepts of Programming Languages

Abstract Types, Algebraic Types, and Type Classes

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

Idris: Implementing a Dependently Typed Programming Language

Simon Peyton Jones Microsoft Research. August 2012

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

Data Types. Every program uses data, either explicitly or implicitly to arrive at a result.

Reasoning about programs. Chapter 9 of Thompson

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

Type Checking and Type Inference

INTRODUCTION TO HASKELL

Simon Peyton Jones Microsoft Research August 2012

Course year Typeclasses and their instances

Functional Logic Programming Language Curry

Introduction to Haskell

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

Advanced Functional Programming

Advanced Functional Programming

DETECTING NON-TERMINATION IN CONSTRAINT HANDLING RULES

Type checking by theorem proving in IDRIS

Introduction to Functional Programming in Haskell 1 / 56

CSc 372 Comparative Programming Languages

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

CSCE 314 Programming Languages

Static Analysis of Haskell

FUNCTIONAL PROGRAMMING NO.9 TYPE AND CLASS. Tatsuya Hagino

CSCI.6962/4962 Software Verification Fundamental Proof Methods in Computer Science (Arkoudas and Musser) Chapter p. 1/27

First-Class Type Classes

An introduction to functional programming. July 23, 2010

Polymorphic Algebraic Data Type Reconstruction

CS 360: Programming Languages Lecture 10: Introduction to Haskell

Intermediate Code Generation Part II

Tracing Ambiguity in GADT Type Inference

Typed Racket: Racket with Static Types

Transcription:

, Martin Sulzmann, Jeremy Wazny 8th November 2006

Chameleon Chameleon is Haskell-style language treats type problems using constraints gives expressive error messages has a programmable type system Developers: Martin Sulzmann, Jeremy Wazny http://www.comp.nus.edu.sg/~sulzmann/chameleon/ Examples taken from Chameleon Caveat Previous versions of Chameleon supported some features No single version shows has all the behaviour we illustrate

Hindley/Milner Types Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Functional Dependencies

What are Types Good for? Type systems are important tools in the design, analysis, and verification of programming languages. Well-typed programs dont go wrong for a reasonable class or errors. Type systems need to Check types! (Preferably) Infer types (Definitely) Explain type errors!

Type Systems are Getting More Complex Fortran types Hindley/Milner types: Higher-order, polymorphic : controlled ad-hoc polymorphism Multiparameter : relations among types Constructor Classes: classes with higher kinds Functional Dependencies: classes with improvement rules Existential Types: objects Lexically Scoped Annotations: more expressive type declarations Guarded Abstract Data Types: types differ per constructor Extended Abstract Data Types: difference controlled by classes...

Thesis Understanding types be first mapping them to constraints: improves understanding inference = satisfiability checking = implication tests eases implementation allows more useful error handling makes type systems easier to extend

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Hindley/Milner Types Types t ::= variable a function arrow t t base types e.g. Char, Bool constructor types e.g. [t] (list of t) Type scheme σ ::= t ā.t Primitive Constraint p ::= t = t True Constraint C ::= p C C

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Hindley/Milner Type Inference f u = g u t False g x y z = if x then z else y Inferring type for g t x = Bool {t x Bool} t ift = t z, t ift = t y {t x Bool, t ift t z, t y t z } t g = t x t y t z t ift {t g Bool t z t z t z } Inferring type for f t g = Bool t 1 t 1 t 1 {t g Bool t 1 t 1 t 1 } t g = t u t gu {t gu t 1 t 1 t 1, t u Bool} t gu = Char t gut {t gut Char Char, t 1 Char} t gut = Bool t body FAILS

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Hindley/Milner Type Inference f u = g u t False g x y z = if x then z else y Error message: Couldn t match Char against Bool Expected type: Char Inferred type: Bool In the third argument of g, namely False In the definition of f : f u = g u t False Fixed order of evaluation Only substitutions are maintained

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Hindley/Milner Type Inference f u = g u t False g x y z = if x then z else y Potential corrected versions of the program: f u = g u True False g x y z = if x then z else y f u = g u t False g x y z = if z then x else y f u = g u t f g x y z = if x then z else y Only the last correction changes the indicated location!

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Locations Collect constraints (not substitutions) Remember locations of constraints Locations l (integers) Justification J ::= ɛ l [l,... l] Primitive constraint p ::= (t = t) J True Location annotated program f u = (((g 1 u 2 ) 3 t 4 ) 5 False 6 ) 7 g x y z = (if 11 x 8 then z 9 else y 10 ) 12 Locations Annotated Type Constraints: (t 1 = t g ) 1, (t 2 = t u ) 2, (t 1 = t 2 t 3 ) 3, (t 4 = Char) 4, (t 3 = t 4 t 5 ) 5, (t 6 = Bool) 6, (t 5 = t 6 t 7 ) 7, t f = t u t 7, (t 8 = t x ) 8, (t 8 = Bool) 11, (t 9 = t z ) 9, (t 10 = t y ) 10, (t 12 = t 9 ) 12, (t 12 = t 10 ) 12, t g = t x t y t z t 12.

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Type Error = Unsatisfiable Constraint Failure of unification = unsatisfiable constraint Minimal unsatisfiable subset: E of constraint D E is unsatisfiable: = E all strict subsets of E are satisfiable: e E. = (E {e}) Minimal unsatisfiable subset = minimal reason for type error!

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Displaying Type Errors Determine a minimal unsatisfiable subset For example: (t 1 = t g ) 1, (t 1 = t 2 t 3 ) 3, (t 4 = Char) 4, (t 3 = t 4 t 5 ) 5, (t 6 = Bool) 6, (t 5 = t 6 t 7 ) 7, (t 9 = t z ) 9, (t 10 = t y ) 10, (t 12 = t 9 ) 12, (t 12 = t 10 ) 12, t g = t x t y t z t 12. Highlight locations of the minimal unsatisfiable subset f u = g u t False g x y z = if x then z else y Not restricted to a single function definition! At least one location highlighted must be changed!

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Multiple Minimal Unsatisfiable Subsets Type information is usually highly redundant. f x = if x then (toupper x) else (tolower x) where toupper,tolower :: Char -> Char f x = if x then (toupper x) else (tolower x) f x = if x then (toupper x) else (tolower x) Locations appearing in all minimal unsatisfiable subsets are more likely to be in error! You may be able to remove all errors changing one f x = if x then (toupper x) else (tolower x)

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Better Error Messages Choose a location from the minimal unsatisfiable subset E Remove the constraints for that location from E (satisfiable) Find conflicting types (via E) at that location Assign a colour to each conflicting type Find the locations causing each conflicting type Report the error in terms of locations and conflicting types Highlight the causes of each conflicting type

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Better Error Messages Example Choose a location: 12 Remove constraints for location: (t 12 = t 9 ) 12, (t 12 = t 10 ) 12 Find conflicting types at location: t 9 = Bool, t 10 = Char Assign a colour to each conflicting type: t 9, t 10 Find the locations causing each conflicting type: t 9 : [1,3,5,6,9], t 10 : [1,3,4,10] Report the error in terms of locations and conflicting types Problem : Then and else branch must have same type Types : Bool Char Conflict: f u = g u t False g x y z = if x then z else y

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Find Locations that Cause a Type? How do we find a minimal set of constraints C that cause another constraint c to hold? Implication: = C c Analogous to finding minimal unsatisfiable subset. Start with E := C Delete a constraint p E: E := E {p} If = E c continue, otherwise replace Stop when no constraint p E can be deleted.

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages A Type Error may not be just Two Conflicting Types! f a b True = error " a " f c True z = error " b " f x y z = if z then x else y GHC: Couldn t match Char against Bool Expected type: Char Inferred type: Bool In the definition of f : f x y z = if z then x else y Chameleon: Problem : Definition clauses not unifiable Types : Char -> a -> b -> c d -> Bool -> e -> f g -> g -> h -> i Conflict: f a b True = error " a " f c True z = error " b " f x y z = if z then x else y

Hindley Milner Type Inference Locations + Minimal Unsatisfiable Constraints Better Error Messages Failure of Type Checking Function type declaration as well as definition h :: a -> (a,b) h x = (x,x) Inferred type: h :: c -> (c,c) Find variable bound in the declared type w.r.t. inferred type b Find minimal implicant of binding b = a Highlight it h.hs:2: ERROR: Inferred type does not subsume declared Declared: forall a,b. a -> (a,b) Inferred: forall a. a -> (a,a) Problem : The variable b makes the declared type too h x = (x, x)

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors : Controlled Overloading A class of types that all supply the same interface: class declarations defined interface class Num a where (+), (-), (*) :: a -> a -> a integer constant :: a instance declarations define members of class instance Num Int where (+) = iplus; (-) = iminus;... instance Num Float where (+) = fplus; (-) = fminus;... Allows overloading (like coercion) e.g. 3.1415 + 2 :: Float

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors : Controlled Overloading A class of types that all supply the same interface: class declarations defined interface class Eq a where (==) :: a -> a -> Bool instance declarations define members of class instance Eq Int where (==) = eqint instance Eq Bool where (==) = eqbool Overloading eqlist:: Eq a => [a] -> [a] -> Bool eqlist [] [] = True eqlist (x:xs) (y:ys) = (x == y) && eqlist xs ys eqlist = False

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Superclasses Classes and instances can require that the members have instances of other classes Class heirarchy class Eq a => Ord a where (>) :: a -> a -> Bool Members of Ord must be members of Eq Instances can also be constrained instance Eq a => Eq [a] where (==) = eqlist

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Multi-Parameter Single parameter type classes implicitly define sets Multi-parameter type classes define relationships among types class Convert a b where upcast :: a -> b downcast :: b -> Maybe a instance Convert Int Float where upcast = frominteger downcast f = if (ceiling f == floor f) then Just (floor f) else Nothing Clearly classes define constraints!

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Primitive constaint p ::= (t = t) J U t True Type scheme σ ::= t ā.c t Class decl cd ::= class (C U ā) l where [m :: (C t) l ] Instance decl id ::= instance (C U t) l where [m = e] We need the ability to Check satisfiability of constraints Check implication of constraints Simplify constraints Check classes and instances agree!

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Constraint Handling Rules (CHRs) Lightweight theorem prover for constraints Maps a set (conjunction) of constraints to an equivalent set of constraints Simplification rules: c 1,..., c n d 1,..., d m Replace lhs by rhs Eq Int <=> True Eq Int is replaced by True (proved) Eq Float <=> True Eq Float is replaced by True (proved) Eq [a] <=> Eq a To prove Eq [a] prove Eq a Propagation rules: c 1,..., c n = d 1,..., d m Add rhs to lhs Ord a ==> Eq a Proving Ord a also requires proving Eq a Derivation Ord [Int] Ord [Int], Eq [Int] Ord [Int], Eq Int Ord [Int]

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Constraint Handling Rules with Justifications Constraint operations need to maintain justifications: Applying a rule c 1,..., c n d 1,..., d m Find matching set c 1,... c n Find equations E that force the match (minimal implicant) Collect justifications J for c 1,... c n and E Remove c 1,... c n Add d 1,..., d m extending justifications by J. Applying Eq [a] <=> (Eq a) 15 to (t 1 = Int) 1, (t 2 = [t 1 ]) 2, (t 3 = t 2 t 4 ) 4, (t 3 = t 5 t 6 ) 6, (Eq t 5 ) 7. minimal implicant of a.t 5 = [a] is (t 2 = [t 1 ]) 2, (t 3 = t 2 t 4 ) 4, (t 3 = t 5 t 6 ) 6 J = [2, 4, 6, 7] Result (t1 = Int) 1, (t 2 = [t 1 ]) 2, (t 3 = t 2 t 4 ) 4, (t 3 = t 5 t 6 ) 6, (Eq t 1 ) [2,4,6,7,15].

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors CHR Algorithms Restrictions on CHR programs Confluent: all derivations for C lead to the same result Terminating: all derivations terminate Range-restricted: all vars in d 1,..., d m appear in c 1,..., c n Single-headed simplification: n = 1 for simplification rules Under these restrictions: Key Results The rules define a canonical form: If P = C 1 C 2 then C 1 D and C 2 D Satisfiability is decidable Minimal unsatisfiable subsets can be determined Implication is decidable Minimal implicants can be determined

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Representing Typing Problems with CHRs Use CHRs to represent types f u = (((g 1 u 2 ) 3 t 4 ) 5 False 6 ) 7 class (True => Eq a) 13 where (==) :: (a -> a -> Bool) 14 instance (Eq a => Eq [a]) 15 where (==) = eqlist 16 is represented as F t f <=> (G t 1 ) 1, (t 2 = t u ) 2, (t 1 = t 2 t 3 ) 3, (t 4 = Char) 4, (t 3 = t 4 t 5 ) 5, (t 6 = Bool) 6, (t 5 = t 6 t 7 ) 7, t f = t u t 7 Eq a ==> True 13 (==) t e <=> (Eq a) 14, (t = a a Bool) 14 Eq [a] <=> (Eq a) 15

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Type Processing using CHRs Type inference: F tf D Inferred type: tf D For example G t g (t 8 = t x) 8, (t 8 = Bool) 11, (t 9 = t z) 9, (t 10 = t y ) 10, (t 12 = t 9) 12, (t 12 = t 10) 12, t g = t x t y t z t 12 Inferred type: t 12.t g = Bool t 12 t 12 Type checking: f :: C t F tf D 1 t f = t, C D 2 = ( tf D 2 ) ( tf D 1 )

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Type Errors with Classes Failure of inference: only possible through unsatisfiable equational constraints Report as before Failure of checking Also possible to have have unmatched type class constraints Extend to report reason (minimal implicant) for these New kinds of errors Missing instance errors Ambiguity errors Incompatible class and instance declarations

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Missing Instance Error Classic beginners mistake: sum [] = [] -- should be 0 sum (x:xs) = x + sum xs Inferred type: sum :: Num [a] => [[a] -> [a] In Haskell 98, each type class constraint appearing in a functions type must be of the form U a where a is a type variable. For Num [a] find a minimal implicant of Num t t.t = [t ] Highlight the locations of the minimal implicant sum.hs:4: ERROR: Missing instance Instance:Num [a]: sum [] = [] -- should be 0 sum (x:xs) = x + sum xs

Constraint Handling Rules Representing Typing Problems with CHRs Type Class Errors Ambiguity Error f x y z = show (if x then read y else read z) where read :: Read a => [Char] -> a and show :: Show a => a -> [Char] Inferred type: f :: forall a.(read a, Show a) => Bool -> [Char] -> [Char] -> [Char] a does not appear in type part. Ambiguous Highlight the positions where a appears in type Ambiguity can be resolved at these locations f x y z = show (if x then read y else read z) For example f x y z = show (if x then (read y)::int else read z)

Functional Dependencies Functional Dependencies class Collects ce e ce -> e where empty :: ce insert :: e -> ce -> ce Collection type ce functionally defines element type e Without this empty :: Collects ce e => ce is ambiguous!

Bibliography Hindley/Milner Types Functional Dependencies Theory P. J. Stuckey and M. Sulzmann. A theory of overloading. ACM TOPLAS, 2005. EADTs M. Sulzmann, J. Wazny, and P.J. Stuckey. A framework for extended algebraic data types. FLOPS 2006, Better error messages P.J. Stuckey, M. Sulzmann, and J. Wazny. Improving type error diagnosis. 2004 ACM Haskell Workshop, Functional dependencies G.J. Duck, S. Peyton-Jones, P.J. Stuckey, and M. Sulzmann. Sound and decidable type inference for functional dependencies. ESOP 2004, Type errors P.J. Stuckey, M. Sulzmann, and J. Wazny. Interactive type debugging in Haskell. 2003 ACM Haskell Workshop, More http://www.comp.nus.edu.sg/~sulzmann/