do-it-yourself dictionaries in haskell

32
Do-it-yourself dictionari es in Haskell 1 Do-it-yourself dictionaries in Haskell Ingmar Brouns & Lukas Spee

Upload: butch

Post on 12-Feb-2016

25 views

Category:

Documents


0 download

DESCRIPTION

Do-it-yourself dictionaries in Haskell. Ingmar Brouns & Lukas Spee. Introduction. Extending the Haskell class system Allowing multiple implementations for one instance of a class declaration. Introduction – examples (1). An example from the Java world: - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 1

Do-it-yourself dictionaries in Haskell

Ingmar Brouns & Lukas Spee

Page 2: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 2

Introduction

• Extending the Haskell class system• Allowing multiple implementations for one

instance of a class declaration

Page 3: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 3

Introduction – examples (1)

• An example from the Java world:Equality: based on reference equivalence or member field value equivalence?

Page 4: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 4

Introduction – example (2)

• In Haskell: Ordering on Strings with the (>) operator:

based on alfabetical order (standard) or on length?

• Filename organizer vs Pretty printer: lexicographical equality vs length equality

Page 5: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 5

Issues

• Not sufficient for examples• We need to extend the class system• How does the current system work ?• What different syntaxes will be an option

(describing with intuitive semantics)• How does the new syntax reflect on the

semantics ?

Page 6: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 6

Current Class System

• Define class & instance declarations• Translation, to a core-Haskell variant

without overloading, by preprocessor• How does this translation work ?

Page 7: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 7

Translation to core-Haskell

• Class declarations are translated to dictionary data type declarations

• Instance declarations are translated to instances of the corresponding dictionary data type

Page 8: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 8

Translation - exampleclass Eq a => Ord a where

(>) :: a -> a -> Bool

data OrdDict a= OrdDict {

gt’ :: a -> a -> Bool,

…}

will be translated to:

Page 9: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 9

Translation - example

instance Ord Char where(>) = primitiveGT

ordDictChar :: OrdDict CharordDictChar = OrdDict {

gt’ = primitiveGT,…}

will be translated to:

Page 10: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 10

Translation - example

foo :: Ord a => a -> a -> Boolfoo = \x y -> x > y

foo :: OrdDict a -> a -> a -> Boolfoo = \ordDict x y ->

gt’ ordDict x y

So, in fact, dictionaries are implicit parameters that ‘control’ the overloading

will be translated to:

Page 11: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 11

Translation - exampleWhich instance of OrdDict a is used for the application of foo depends on the types of the parameters, thus:foo ‘a’ ‘b’

will be translated to:

foo ordDictChar ‘a’ ‘b’

Page 12: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 12

Back to our example

• We now have an instance of Ord for Char• We need an instance of Ord for String

([Char])• Can we construct it from our Ord Char

instance ?

Page 13: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 13

Back to our exampleYes, but we need an instance of Ord [a] for this:instance Ord a => Ord [a] where

(>) [] _ = False(>) _ [] = True(>) (x:xs) (y:ys) = (x > y) &&

(xs > ys)

Page 14: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 14

A dictionary for Ord [a]ordDictList :: OrdDict a -> OrdDict [a]ordDictList ordD = OrdDict (ordList ordD)

ordList :: OrdDict a -> [a] -> [a] -> BoolordList ordDict (x:xs) [] = TrueordList ordDict [] (y:ys) = FalseordList ordDict (x:xs) (y:ys) =

gt’ ordDict x y && gt’ (ord ordDict) xs ys

Please remember this for one more slide

Page 15: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 15

A dictionary for Ord [Char]Now we can easily combine the two to create the dictionary for Ord String:ordDictString = ordDictList ordDictChar

That’s nice, but how is it going to solve our problem?

Page 16: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 16

Dictionaries are the answer!

• If we want a new implementation for (>) on String, we’ll make it and put it in our own dictionary

• Wherever we want to use this dictionary instead of the implicitly passed default dictionary, we make this explicit

Page 17: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 17

Back to our example

getMaximumSize :: String -> String -> Int

getMaximumSize {impl2} = \x y -> if x > y then (length x) else (length y)

(>) :: String -> String -> Bool

(>) = \x y -> (length x) > (length y)

Suppose we have our own dictionary for Ord [Char] called ‘impl2’ which defines (>) as:

We can now explicitly pass this dictionary to a function:

Page 18: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 18

Extending the syntax

• Several attempts• What are the drawbacks ?• How can they be avoided ?

Page 19: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 19

Attempt 1Allow users to define dictionaries explicitlyinstance Ord [Char] where

(>) [] _ = False(>) _ [] = True(>) (x:xs) (y:ys) = (x > y) &&

(xs > ys)...

ordDictString’ = OrdDict { gt’ = (\a b -> compare (length a)

(length b) == GT),...}

Page 20: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 20

Attempt 1

• Drawbacks:• User has to be familiar dictionaries as used

in core-Haskell• Dictionary is copied so user must use

implementations of overloaded functions in definition

• Implementation is no longer hidden

Page 21: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 21

Attempt 2• Define extra implementation within

instance declaration• Tag the extra implementation

instance Ord [Char] where(>) [] _ = False(>) _ [] = True(>) (x:xs) (y:ys) = (x > y) &&

(xs > ys)(>) a b = length a > length b {impl2}

Page 22: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 22

Attempt 2

• Good things:– Implementation not visible to user– Consistent with existing syntax

• Drawbacks– Unhandy when using modules

Page 23: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 23

Attempt 3 Name the instance declaration

impl2 = instance Ord [Char] where(>) a b = length a > length b

Capable of modifying instances in other modules

Page 24: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 24

Attempt 4 Which instance declaration do we want to override ?

Impl2 overrides impl = instance Ord [Char]where(>) a b = length a > length b

When no overrides statement -> defaultOnly one default allowed, explicit or implicitly defined

Page 25: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 25

Type Checking

Where do we need to do new checks ?• Type checks:

– Type of new implementation should correspond to type of overridden implementation

– explicit dictionary usage should have same type as declared in explicit type

Page 26: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 26

Formal typing / translation rules

Page 27: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 27

Formal typing / translation rules

• Now:– gt :: Ord a => a -> a -> Bool

• Will be written as– gt :: forall a. (ord :: Ord a) . a -> a ->

Bool

• Eq a is an abbrevation for (a -> a -> Bool)• But now the important part !!!

Page 28: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 28

Typing / translation rules

• Translation is controlled by typing

A,(ord :: Ord Char \ ordDictChar) |- e :: p \ ē

A |- e :: (ord :: Ord Char).p \ (\ ordDictChar. ē)

• In the current system, there can only be one instance with a certain type

• In our system this is not the case

Page 29: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 29

Typing / translation rules

• Result:• Translation is no longer only type driven• Now also name driven• For example not passing a list of

dictionaries, but a list of (name, dictionary) tuples.

Page 30: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 30

Implementation issues for UHC

• Preprocessor has to be adjusted– Overriding dictionary should have same type as

overridden dictionary– Named dictionaries have to be generated– So the context for passing dictionaries will have

to be adjusted– User defined dictionary usage has to be type

checked

Page 31: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 31

Conclusion

• Allowing users to define alternative implementations of class instances, gives them more freedom.

• Formal typing rules do not change, only the translation is now also dependent of names

• Some extra type checks will be needed• It is possible to implement this in UHC

Page 32: Do-it-yourself dictionaries in Haskell

Do-it-yourself dictionaries in Haskell 32

Questions

1. Now it is the case that the translation is purely type driven. What is the case with our extension, and explain why it is like that ?

2. How does this affect the existing typing rules ?

3. Explain the use of our overrides statement.