Advanced Type System Features Tom Schrijvers. Leuven Haskell User Group

Similar documents
Bringing Functions into the Fold Tom Schrijvers. Leuven Haskell User Group

Type families and data kinds

GADTs. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 7. [Faculty of Science Information and Computing Sciences]

GADTs. Wouter Swierstra. Advanced functional programming - Lecture 7. Faculty of Science Information and Computing Sciences

GADTs. Alejandro Serrano. AFP Summer School. [Faculty of Science Information and Computing Sciences]

IA014: Advanced Functional Programming

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

Logic - CM0845 Introduction to Haskell

Advanced features of Functional Programming (Haskell)

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

Programming with Math and Logic

Advances in Programming Languages

CSCE 314 Programming Languages Functors, Applicatives, and Monads

Lecture 8: Summary of Haskell course + Type Level Programming

Type Classes in Haskell Tom Schrijvers. Leuven Haskell User Group

Outline. Introduction Concepts and terminology The case for static typing. Implementing a static type system Basic typing relations Adding context

GADTs. GADTs in Haskell

Shell CSCE 314 TAMU. Functions continued

Informatics 1 Functional Programming Lecture 9. Algebraic Data Types. Don Sannella University of Edinburgh

Lecture 4: Higher Order Functions

Dependent Polymorphism. Makoto Hamana

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

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

# true;; - : bool = true. # false;; - : bool = false 9/10/ // = {s (5, "hi", 3.2), c 4, a 1, b 5} 9/10/2017 4

Introduction to ML. Based on materials by Vitaly Shmatikov. General-purpose, non-c-like, non-oo language. Related languages: Haskell, Ocaml, F#,

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

EECS 700 Functional Programming

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

Overloading, Type Classes, and Algebraic Datatypes

Haskell An Introduction

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

CS 457/557: Functional Languages

CS 320: Concepts of Programming Languages

Week 5 Tutorial Structural Induction

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

Haskell Introduction Lists Other Structures Data Structures. Haskell Introduction. Mark Snyder

State Monad (3D) Young Won Lim 9/25/17

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

A general introduction to Functional Programming using Haskell

Algebraic Types. Chapter 14 of Thompson

Extended Static Checking for Haskell (ESC/Haskell)

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

News. Programming Languages. Complex types: Lists. Recap: ML s Holy Trinity. CSE 130: Spring 2012

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

Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Booleans and Short-Circuit Evaluation. Tuples as Values.

Shared Subtypes. Subtyping Recursive Parameterized Algebraic Data Types

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

Types in Programming Languages Dynamic and Static Typing, Type Inference (CTM 2.8.3, EPL* 4) Abstract Data Types (CTM 3.7) Monads (GIH** 9)

FUNCTIONAL PEARLS The countdown problem

Programming in Omega Part 1. Tim Sheard Portland State University

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

Concepts of program design Exam January 31, 13:30 16:30

Informatics 1 Functional Programming Lecture 12. Data Abstraction. Don Sannella University of Edinburgh

Informatics 1 Functional Programming Lecture 11. Data Representation. Don Sannella University of Edinburgh

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

Lecture 19: Functions, Types and Data Structures in Haskell

Standard prelude. Appendix A. A.1 Classes

An introduction introduction to functional functional programming programming using usin Haskell

Embedded Domain Specific Language Implementation using Dependent Types

These notes are intended exclusively for the personal usage of the students of CS352 at Cal Poly Pomona. Any other usage is prohibited without

List Functions, and Higher-Order Functions

CSc 372 Comparative Programming Languages

Principles of Programming Languages

Programming Languages

02157 Functional Programming. Michael R. Ha. Disjoint Unions and Higher-order list functions. Michael R. Hansen

Topic 7: Algebraic Data Types

Exercise 1 (2+2+2 points)

Pierce Ch. 3, 8, 11, 15. Type Systems

Applicative, traversable, foldable

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

Programming Languages

Haskell Type Constraints Unleashed

Types and Type Inference

Haskell: From Basic to Advanced. Part 2 Type Classes, Laziness, IO, Modules

Structural polymorphism in Generic Haskell

Type checking by theorem proving in IDRIS

Lists. Michael P. Fourman. February 2, 2010

PROGRAMMING IN HASKELL. Chapter 5 - List Comprehensions

Applicative, traversable, foldable

Verifying the darcs patch code

Lists. Adrian Groza. Department of Computer Science Technical University of Cluj-Napoca

Introduction to Functional Programming in Haskell 1 / 56

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

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

CS 11 Haskell track: lecture 1

Trees. Solution: type TreeF a t = BinF t a t LeafF 1 point for the right kind; 1 point per constructor.

Programming in Haskell Aug Nov 2015

Many Holes in Hindley-Milner

The Worker/Wrapper Transformation

Type-indexed functions in Generic Haskell

Programming Languages

Announcements. CSCI 334: Principles of Programming Languages. Lecture 5: Fundamentals III & ML

CITS3211 FUNCTIONAL PROGRAMMING. 7. Lazy evaluation and infinite lists

Haskell Refresher Informatics 2D

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

Static Contract Checking for Haskell

Mini-ML. CS 502 Lecture 2 8/28/08

Lightweight Invariants with Full Dependent Types

CS 209 Functional Programming

CSCE 314 Programming Languages

Transcription:

Advanced Type System Features Tom Schrijvers Leuven Haskell User Group

Data Recursion Genericity Schemes Expression Problem Monads GADTs DSLs Type Type Families Classes Lists and Effect Free Other Handlers Theorems Monoids

Data Recursion Genericity Schemes Expression Problem Monads GADTs GADTS DSLs Type Type Families Classes Lists and Effect Free Other Handlers Theorems Monoids

Static Type System

Static Type System Lightweight specifications Verified / enforced by the type checker

Static Type System

Static Type System Rules out many invalid programs

Static Type System Rules out many invalid programs Rules out some valid programs

Advanced Type Systems accept more valid programs accept fewer invalid programs

Advanced Type Systems accept more valid programs Java 5 generics Java 4 accept fewer invalid programs

A Problem with Expressions

Expressions data Exp = ILit Int Add Exp Exp eval :: Exp -> Int eval (ILit n) = n eval (Add e1 e2) = eval e1 + eval e2

More Expressions data Exp = ILit Int Add Exp Exp BLit Bool

Revised Evaluator eval :: Exp -> Int eval (ILit n) = n eval (Add e1 e2) = eval e1 + eval e2 eval (BLit b) = b

Revised Evaluator eval :: Exp -> Int eval (ILit n) = n eval (Add e1 e2) = eval e1 + eval e2 eval (BLit b) = b

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Val eval (ILit n) = n eval (Add e1 e2) = eval e1 + eval e2 eval (BLit b) = b

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Val eval (ILit n) = n eval (Add e1 e2) = eval e1 + eval e2 eval (BLit b) = b

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Val eval (ILit n) = IVal n eval (Add e1 e2) = IVal (eval e1 + eval e2) eval (BLit b) = BVal b

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Val eval (ILit n) = IVal n eval (Add e1 e2) = IVal (eval e1 + eval e2) eval (BLit b) = BVal b

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Val eval (ILit n) = IVal n eval (Add e1 e2) = case (eval e1, eval e2) of (IVal n1, IVal n2) -> IVal (n1+n2) eval (BLit b) = BVal b

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Val eval (ILit n) = IVal n eval (Add e1 e2) = case (eval e1, eval e2) of (IVal n1, IVal n2) -> IVal (n1+n2) _ ->??? eval (BLit b) = BVal b

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Maybe Val eval (ILit n) = IVal n eval (Add e1 e2) = case (eval e1, eval e2) of (IVal n1, IVal n2) -> IVal (n1+n2) _ -> Nothing eval (BLit b) = BVal b

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Maybe Val eval (ILit n) = IVal n eval (Add e1 e2) = case (eval e1, eval e2) of (IVal n1, IVal n2) -> IVal (n1+n2) _ -> Nothing eval (BLit b) = BVal b

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Maybe Val eval (ILit n) = Just (IVal n) eval (Add e1 e2) = case (eval e1, eval e2) of (IVal n1, IVal n2) -> Just (IVal (n1+n2)) _ -> Nothing eval (BLit b) = Just (BVal b)

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Maybe Val eval (ILit n) = Just (IVal n) eval (Add e1 e2) = case (eval e1, eval e2) of (IVal n1, IVal n2) -> Just (IVal (n1+n2)) _ -> Nothing eval (BLit b) = Just (BVal b)

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Maybe Val eval (ILit n) = Just (IVal n) eval (Add e1 e2) = case (eval e1, eval e2) of (Just (IVal n1), Just (IVal n2)) -> Just (IVal (n1+n2)) _ -> Nothing eval (BLit b) = Just (BVal b)

Revised Evaluator data Val = IVal Int BVal Bool eval :: Exp -> Maybe Val eval (ILit n) = Just (IVal n) eval (Add e1 e2) Overhead due to possibly ill-typed expressions = case (eval e1, eval e2) of (Just (IVal n1), Just (IVal n2)) -> Just (IVal (n1+n2)) _ -> Nothing eval (BLit b) = Just (BVal b)

GADTs to the Rescue

The Problem admits invalid values Exp

The Problem admits invalid values Exp Add (BLit True) (ILit 5)

The Problem accept more valid programs admits invalid values Exp accept fewer invalid programs

The Problem accept more valid programs admits invalid values Exp GADTs accept fewer invalid programs

The Problem accept more valid programs admits invalid values Exp Exp a GADTs accept fewer invalid programs

The Problem accept more valid programs admits invalid values Exp admits only valid values Exp a GADTs accept fewer invalid programs

Parametrised Expressions Exp a

Parametrised Expressions Expressions that yield a value of type a type a Exp a

Parametrised Expressions Expressions that yield a value of type a type a Exp a indexed family index

Parametrised Expressions Expressions that yield a value of type a type a Exp a indexed family index family members Exp Int Exp Bool

Parametrised Expressions Expressions that yield a value of type a type a Exp a indexed family index family members Exp Int Exp Bool ILit 0 Add (ILit 1) (ILit 2)

Parametrised Expressions Expressions that yield a value of type a type a Exp a indexed family index family members Exp Int ILit 0 Exp Bool BLit True Add (ILit 1) (ILit 2) BLit False

Generalized Algebraic Data Type data Exp where ILit :: Int -> Exp Add :: Exp -> Exp -> Exp BLit :: Bool -> Exp

Generalized Algebraic Data Type data Exp a where ILit :: Int -> Exp Int Add :: Exp Int -> Exp Int -> Exp Int BLit :: Bool -> Exp Bool

Generalized Algebraic Data Type indexed family data Exp a where ILit :: Int -> Exp Int Add :: Exp Int -> Exp Int -> Exp Int BLit :: Bool -> Exp Bool

Generalized Algebraic Data Type indexed family Refined index data Exp a where ILit :: Int -> Exp Int Add :: Exp Int -> Exp Int -> Exp Int BLit :: Bool -> Exp Bool

GADT Evaluator eval :: Exp a -> a eval (ILit n) = n eval (Add e1 e2) = eval e1 + eval e2 eval (BLit b) = b

GADT Evaluator eval :: Exp a -> a No noise due to possibly ill-typed expressions! eval (ILit n) = n eval (Add e1 e2) = eval e1 + eval e2 eval (BLit b) = b

GADT Evaluator eval :: Exp a -> a No noise due to possibly ill-typed expressions! eval (ILit n) = n From the pattern match we know that a = Int eval (Add e1 e2) = eval e1 + eval e2 eval (BLit b) = b

GADT Evaluator eval :: Exp a -> a No noise due to possibly ill-typed expressions! eval (ILit n) = n From the pattern match we know that a = Int eval (Add e1 e2) = eval e1 + eval e2 eval (BLit b) = b From the pattern match we know that a = Bool

GADT Extension data Exp a where ILit :: Int -> Exp Int Add :: Exp Int -> Exp Int -> Exp Int BLit :: Bool -> Exp Bool IfThenElse :: Exp Bool -> Exp a -> Exp a -> Exp a

Extended GADT Evaluator eval :: Exp a -> a eval (ILit n) = n eval (Add e1 e2) = eval e1 + eval e2 eval (BLit b) = b eval (IfThenElse i t e) = if eval i then eval t else eval e

Alternative Syntax data Exp = ILit Int Add (Exp ) (Exp ) BLit Bool

Alternative Syntax data Exp a = a ~ Int => ILit Int a ~ Int => Add (Exp Int) (Exp Int) a ~ Bool => BLit Bool

Alternative Syntax data Exp a = a ~ Int => ILit Int a ~ Int => Add (Exp Int) (Exp Int) a ~ Bool => BLit Bool Equality Constraint

Alternative Syntax data Exp a = a ~ Int => ILit Int a ~ Int => Add (Exp Int) (Exp Int) a ~ Bool => BLit Bool Equality Constraint a ~ Int a equals Int

Ensure & Assume Construct value ILit n :: Exp a Type checker has to assure that a ~ Int

Ensure & Assume Construct value ILit n :: Exp a Type checker has to assure that a ~ Int Deconstruct value case e :: Exp a of ILit n -> body Type checker can assume that a ~ Int

Length-Indexed Lists with GADTs

Regular Lists data List a = Nil Cons a (List a) head :: List a -> a head (Cons x xs) = x

Regular Lists data List a = Nil Cons a (List a) head :: List a -> a head (Cons x xs) = x

Regular Lists data List a = Nil Cons a (List a) head :: List a -> a head (Cons x xs) = x crashes on empty list!

The Problem crashes on empty list head List a

The Problem crashes on empty list head List a head Nil

The Problem accept more valid programs crashes on empty list head List a accept fewer invalid programs

The Problem accept more valid programs crashes on empty list head List a GADTs accept fewer invalid programs

The Problem accept more valid programs crashes on empty list head List a head List n a GADTs accept fewer invalid programs

The Problem accept more valid programs crashes on empty list head List a does not accept head Nil head List n a GADTs accept fewer invalid programs

Length-Indexed Lists List n a

Length-Indexed Lists List n a indexed family index

Length-Indexed Lists List n a indexed family index family members List Z a List (S Z) a List (S (S Z)) a

Length-Indexed Lists List n a indexed family index family members List Z a List (S Z) a List (S (S Z)) a Nil Cons x Nil Cons x (Cons y)ni

Length-Index List GADT data List a where Nil :: List a Cons :: a -> List a -> List a

Length-Index List GADT data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a

Length-Index List GADT indexed family data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a

Length-Index List GADT indexed family Refined index data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a

Length-Index List GADT indexed family Refined index data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a data Z data S n Empty data types: only used as type indices

Safe Head data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a head :: List a -> a head (Cons x xs) = x

Safe Head data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a head :: List (S n) a -> a head (Cons x xs) = x

Safe Head data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a head :: List (S n) a -> a head (Cons x xs) = x > head Nil Couldn't match type Z with S n0 Expected type: List (S n0) a Actual type: List Z a In the first argument of head, namely Nil In the expression: head Nil

Safe Zip data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a zip :: List a -> List b -> List (a,b) zip Nil Nil = Nil zip (Cons x xs) (Cons y ys) = Cons (x,y) (zip xs ys) lists of different length!

Safe Zip data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a zip :: List n a -> List n b -> List n (a,b) zip Nil Nil = Nil zip (Cons x xs) (Cons y ys) = Cons (x,y) (zip xs ys)

Type Families

Append? data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a append :: List n a -> List m a -> List? a append Nil ys = ys append (Cons x xs) ys = Cons x (append xs ys)

Append? data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a append :: List n a -> List m a -> List? a append Nil ys n + m = ys append (Cons x xs) ys = Cons x (append xs ys)

Append? data List n a where Nil :: List Z a Cons :: a -> List n a -> List (S n) a append :: List n a -> List m a -> List? a append Nil ys n + m = ys append (Cons x xs) ys = Cons x (append xs ys) type-level computation

The Problem append

The Problem accept more valid programs append accept fewer invalid programs

The Problem accept more valid programs Type Families append accept fewer invalid programs

The Problem accept more valid programs append Type Families append accept fewer invalid programs

Type Family aka Type Function type family Add n m where Add Z m = m Add (S n) m = S (Add n m)

Append with Type Family type family Add n m where Add Z m = m Add (S n) m = S (Add n m) append :: List n a -> List m a -> List (Add n m) a append Nil ys = ys append (Cons x xs) ys = Cons x (append xs ys)

Open & Associated Type Families

Collect Type Class class Collect c where insert :: c ->? -> c

Elem Type Family (open) type class declaration class Collect c where insert :: c -> Elem c -> c type family Elem c open type family declaration

Instances type class instance instance Collect [e] where insert l c = c : l type instance Elem [e] = e type family instance

Open Nature type instance Elem [e] = e instance Collect [e] where insert l c = c : l type instance Elem ByteString = Word8 instance Collect ByteString where insert l c = cons c l

Open Nature type instance Elem [e] = e instance Collect [e] where insert l c = c : l type instance Elem ByteString = Word8 instance Collect ByteString where insert l c = cons c l double instances

Associated Type Family class Collect c where type Elem c insert :: c -> Elem c -> c instance Collect [e] where type Elem [e] = e insert l c = c : l instance Collect ByteString where type Elem ByteString = Word8 insert l c = cons c l

Associated Type Family class Collect c where type Elem c insert :: c -> Elem c -> c instance Collect [e] where type Elem [e] = e insert l c = c : l instance Collect ByteString where type Elem ByteString = Word8 insert l c = cons c l

Summary

Advanced Type System Features Generalised Algebraic Data Types Type-level Functions aka Type Families

Advanced Type System Features Generalised Algebraic Data Types Type-level Functions aka Type Families accept more valid programs accept fewer invalid programs

More To Learn Existential Types Rank-n Polymorphism Kinds: Type Promotion, Kind Polymorphism Type Classes: Functional Dependencies, Resolution Extensions Value-Dependent Types (beyond Haskell)

Next time: 19/5/2015

Data Recursion Genericity Schemes Expression Problem Monads GADTs DSLs Type Type Families Classes Lists and Effect Free other Handlers Theorems Monoids

Data Recursion Genericity Schemes Expression Problem Monads GADTs DSLs Type Type Families Classes Lists Quattro Stagioni Effect Free Handlers Theorems other of Haskell Monoids and

Join the Google Group Leuven Haskell User Group