Instances for Free* Neil Mitchell (* Postage and packaging charges may apply)

Similar documents
Deriving Generic Functions by Example

Deriving Generic Functions by Example

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

Logic - CM0845 Introduction to Haskell

Lecture 4: Higher Order Functions

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

CS 320: Concepts of Programming Languages

Functional Programming Mid-term exam Tuesday 3/10/2017

Abstract Types, Algebraic Types, and Type Classes

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

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

Overview. Declarative Languages D7012E. Overloading. Overloading Polymorphism Subtyping

CSE399: Advanced Programming. Handout 2

(ii) Define a function ulh that takes a list xs, and pairs each element with all other elements in xs.

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

CSC324 Principles of Programming Languages

CSc 372. Comparative Programming Languages. 18 : Haskell Type Classes. Department of Computer Science University of Arizona

CS 320: Concepts of Programming Languages

Witnessing Purity, Constancy and Mutability APLAS Ben Lippmeier Australian National University 2009/12/14

Fastest Lambda First. Neil Mitchell.

Lecture 10 September 11, 2017

MoreIntro_annotated.v. MoreIntro_annotated.v. Printed by Zach Tatlock. Oct 04, 16 21:55 Page 1/10

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

CSC324 Principles of Programming Languages

Course year Typeclasses and their instances

MoreIntro.v. MoreIntro.v. Printed by Zach Tatlock. Oct 07, 16 18:11 Page 1/10. Oct 07, 16 18:11 Page 2/10. Monday October 10, 2016 lec02/moreintro.

CS 360: Programming Languages Lecture 12: More Haskell

Introduction to Functional Programming in Haskell 1 / 56

QuickCheck, SmallCheck & Reach: Automated Testing in Haskell. Tom Shackell

Functional Programming and Haskell

CSCE 314 Programming Languages

Software System Design and Implementation

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

CSCE 314 Programming Languages

Programming Paradigms

Exercises on ML. Programming Languages. Chanseok Oh

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

CS 440: Programming Languages and Translators, Spring 2019 Mon

Shell CSCE 314 TAMU. Higher Order Functions

Type Processing by Constraint Reasoning

CS 457/557: Functional Languages

Type-indexed functions in Generic Haskell

Type families and data kinds

Overloading, Type Classes, and Algebraic Datatypes

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

Functional Programming - 2. Higher Order Functions

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

The Algebra of Programming in Haskell

Haskell Making Our Own Types and Typeclasses

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

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

Standard prelude. Appendix A. A.1 Classes

Haskell Refresher Informatics 2D

Faster Haskell. Neil Mitchell

Giving Haskell a Promotion

A general introduction to Functional Programming using Haskell

Transformation and Analysis of Haskell Source Code

Uniform Boilerplate and List Processing

INTRODUCTION TO FUNCTIONAL PROGRAMMING

CSCI-GA Scripting Languages

Optimising Functional Programming Languages. Max Bolingbroke, Cambridge University CPRG Lectures 2010

Structural polymorphism in Generic Haskell

Ready, Set, Verify! Applying hs-to-coq to Real-World Haskell Code (Experience Report)

Higher Order Functions in Haskell

CS 320 Homework One Due 2/5 11:59pm

CSE 3302 Programming Languages Lecture 8: Functional Programming

Advances in Programming Languages

Explicit Recursion in Generic Haskell

INTRODUCTION TO HASKELL

IA014: Advanced Functional Programming

Algebraic Types. Chapter 14 of Thompson

Monads seen so far: IO vs Gen

CMSC 330: Organization of Programming Languages

Introduction to Functional Programming using Haskell

Alloy tutorial. Neil C. C. Brown. June 8, 2009

User-Defined Algebraic Data Types

CSCE 314 Programming Languages

Topic 5: Higher Order Functions

Topic 5: Higher Order Functions

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

CS 320 Midterm Exam. Fall 2018

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

Lecture 5: Lazy Evaluation and Infinite Data Structures

Exercise 1 ( = 22 points)

Programming with Math and Logic

FUNCTIONAL PROGRAMMING NO.9 TYPE AND CLASS. Tatsuya Hagino

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

Exercise 1 (2+2+2 points)

Static Analysis of Haskell

Simple Unification-based Type Inference for GADTs

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

Topic 6: Partial Application, Function Composition and Type Classes

Topic 6: Partial Application, Function Composition and Type Classes

Developing Good Habits for Bare-Metal Programming

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

Lecture #23: Conversion and Type Inference

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

CS 457/557: Functional Languages

Data types à la carte

Lazy Functional Programming in Haskell

Transcription:

Instances for Free* Neil Mitchell www.cs.york.ac.uk/~ndm (* Postage and packaging charges may apply)

Haskell has type classes f :: Eq a => a -> a -> Bool f x y = x == y Polymorphic (for all type a) Provided they support Eq

Defining Type Classes class Eq a where (==) :: a -> a -> Bool data MyType = instance Eq MyType where a == b =

Some Eq instances (1) data List a = Nil Cons a (List a) instance Eq a => Eq (List a) where Nil == Nil = True Cons x1 x2 == Cons y1 y2 = x1 == y1 && x2 == y2 _ == _ = False

Some Eq instances (2) data Maybe a = Nothing Just a instance Eq a => Eq (Just a) where Nothing == Nothing = True Just x1 == Just y1 = x1 == y1 _ == _ = False

Some Eq instances (3) data Unit = Unit instance Eq Unit where Unit == Unit = True _ == _ = False

Some Eq instances (4) data Either a b = Left a Right b instance (Eq a, Eq b) => Eq (Either a b) where Left x1 == Left x2 = x1 == x2 Right x1 == Right x2 = x1 == x2 _ == _ = False

Please, no more Eq instances! In the base library there are 433 types with Eq instances A lot of tedious code Fortunately, Haskell has a solution data MyType = deriving Eq

Limitations of deriving Can only derive 6 classes Eq, Ord, Enum, Bounded, Show, Read But there are lots more classes out there class Serial a where series :: Series a coseries :: Series b -> Series (a->b)

Solution: A preprocessor DrIFT was the original solution Run a preprocessor to generate the instances Derive is a competitor to DrIFT Can directly integrate with GHC Preprocessor optional Can work better with version control Supports more Haskell features

How DrIFT works Has a representation of Haskell types data HsType = HsType [Variable] [HsCtor] data HsCtor = HsCtor CtorName [HsField] Author of the class must define deriveserial :: HsType -> String

How Derive works And a representation of Haskell code too data Stmt = data Expr = Lots of constructors, types etc. Author of the class must define deriveserial :: HsType -> [Stmt]

Derive difficulties So the author of the Serial class must Learn and understand HsType Learn and understand Stmt, Expr etc. Write an instance generator Check it on several examples Lots of work for Colin!

A simpler solution Give Colin a single data type Ask for a sample instance data DataName a = CtorZero CtorOne a CtorTwo a a CtorTwo' a a

Colin replies instance Serial a => Serial (DataName a) where series = cons0 CtorZero \/ cons1 CtorOne \/ cons2 CtorTwo \/ cons2 CtorTwo data DataName a = CtorZero CtorOne a CtorTwo a a CtorTwo' a a

Derive replies [instance [Serial] Serial ] [series = foldr1 (\/) ] [(cons +$ arity c) (name c) c <- ctors] a +$ b = a ++ show b instance Serial a => Serial (DataName a) where series = cons0 CtorZero \/ cons1 CtorOne \/ cons2 CtorTwo \/ cons2 CtorTwo

Derivation by Example We gave Derive one single example Over a particular data type Derive has a domain specific language for instances Given an example, it infers a program

Instance for Eq instance Eq a => Eq (DataName a) where CtorZero == CtorZero = True (CtorOne x1) == (CtorOne y1) = x1 == y1 && True (CtorTwo x1 x2) == (CtorTwo y1 y2) = x1 == y1 && x2 == y2 && True (CtorTwo x1 x2) == (CtorTwo y1 y2) = x1 == y1 && x2 == y2 && True _ == _ = False

Instance Example [instance [Eq] Eq [ [(name c) [x +$ i i <- [1..arity c]] == [(name c) [y +$ i i <- [1..arity c]] = foldr (&&) True [x+$ i == y+$ i i <- [1..arity c]] c <- ctors] ++ [ _ == _ = False ] ]

What is in the Derive Language? map, foldr, foldl, foldr1, foldl1, reverse +$, ++ ctors arity, name, tag Properties over a constructor numbers instance

Instance Derivation by Example Given an example for the data type Infer an instance Key property: If a derivation program is correct It must be equivalent to all other correct derivations

Uniqueness If only minimal derivations are considered, then the derivations are unique Minimal = no redundant operations Achieved by bounding the domain language and selecting the data type

Example of Uniqueness For Serial, constructors map to arity For Enum, constructors map to tags cons2 CtorTwo \/ cons2 CtorTwo fromenum CtorTwo = 2 fromenum CtorTwo = 3

Limitations Can t deal with: Records Type based derivations Derive language cannot express these If they were added, the data type would have to become more complex (a lot!)

Summary so far Derive lets you write one example Infers the pattern Works a lot of the time (~ 60%) Next Basic idea behind the inference Gets more technical

Develop a theory The inference is bottom up Develops theories about syntactic bits Combines these theories CtorZero (\i -> name i) CtorZero CtorOne (\i -> name i) CtorOne

More theories cons0 (\i -> cons +$ i) 0 cons1 (\i -> cons +$ i) 1 /\ (\_ -> /\) () Theories are parameterised by (), number, or a constructor

Promoting theories theory () theory <anything> theory 0 (theory. arity) CtorZero theory 0 (theory. tag) CtorZero (\i -> cons +$ i) 0 (\i -> cons +$ arity i) CtorZero (\i -> cons +$ tag i) CtorZero Nondeterministic

Theory application x x t f f t f x (\t -> (f t) (x t)) t (f <*> x ) t The S combinator

Theory lists xi xi ti forall i. xi ti == xj t In practice, all xi are usually identical tn expand t forall i. (expand t!! i) == ti [x1..xn] (map xj. expand) t

Theory expansions n (enumfromto 1) n (enumfromto 0) n CtorTwo ctors () [1,2,3] (map id. enumfromto 1) 3 [CtorZero..CtorTwo ] (map id. ctors) ()

Adding in folds Just do a translation first x1 `f` `f` xn == foldr1 f [x1 xn] Reverse is handled in the same way

Combined together cons0 CtorZero cons0 (\i -> cons +$ i) 0 (\i -> cons +$ arity i) CtorZero CtorZero (\i -> name i) CtorZero cons0 CtorZero (\i -> (name i) (cons +$ arity i)) CtorZero

More combining [cons0 CtorZero, cons1 CtorOne, [(\i -> (name i) (cons +$ arity i)) CtorZero,(\i -> (name i) (cons +$ arity i)) CtorOne (map (\i -> (name i) (cons +$ arity i)). ctors) ()

Conclusions The inference method is not too hard Usually just does the right thing If you really want to derive Serial, see: http://www-users.cs.york.ac.uk/~ndm/derive/