ca76dcb5fd373a9833054917477be741.ppt
- Количество слайдов: 32
Do-it-yourself dictionaries in Haskell Ingmar Brouns & Lukas Spee Do-it-yourself dictionaries in Haskell 1
Introduction • Extending the Haskell class system • Allowing multiple implementations for one instance of a class declaration Do-it-yourself dictionaries in Haskell 2
Introduction – examples (1) • An example from the Java world: Equality: based on reference equivalence or member field value equivalence? Do-it-yourself dictionaries in Haskell 3
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 Do-it-yourself dictionaries in Haskell 4
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 ? Do-it-yourself dictionaries in Haskell 5
Current Class System • Define class & instance declarations • Translation, to a core-Haskell variant without overloading, by preprocessor • How does this translation work ? Do-it-yourself dictionaries in Haskell 6
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 Do-it-yourself dictionaries in Haskell 7
Translation - example class Eq a => Ord a where (>) : : a -> Bool will be translated to: data Ord. Dict a = Ord. Dict { gt’ : : a -> Bool, …} Do-it-yourself dictionaries in Haskell 8
Translation - example instance Ord Char where (>) = primitive. GT will be translated to: ord. Dict. Char : : Ord. Dict Char ord. Dict. Char = Ord. Dict { gt’ = primitive. GT, …} Do-it-yourself dictionaries in Haskell 9
Translation - example foo : : Ord a => a -> Bool foo = x y -> x > y will be translated to: foo : : Ord. Dict a -> Bool foo = ord. Dict x y -> gt’ ord. Dict x y So, in fact, dictionaries are implicit parameters that ‘control’ the overloading Do-it-yourself dictionaries in Haskell 10
Translation - example Which instance of Ord. Dict a is used for the application of foo depends on the types of the parameters, thus: foo ‘a’ ‘b’ will be translated to: foo ord. Dict. Char ‘a’ ‘b’ Do-it-yourself dictionaries in Haskell 11
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 ? Do-it-yourself dictionaries in Haskell 12
Back to our example Yes, 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) Do-it-yourself dictionaries in Haskell 13
A dictionary for Ord [a] ord. Dict. List : : Ord. Dict a -> Ord. Dict [a] ord. Dict. List ord. D = Ord. Dict (ord. List ord. D) ord. List : : Ord. Dict a -> [a] -> Bool ord. List ord. Dict (x: xs) [] = True ord. List ord. Dict [] (y: ys) = False ord. List ord. Dict (x: xs) (y: ys) = gt’ ord. Dict x y && gt’ (ord ord. Dict) xs ys Please remember this for one more slide Do-it-yourself dictionaries in Haskell 14
A dictionary for Ord [Char] Now we can easily combine the two to create the dictionary for Ord String: ord. Dict. String = ord. Dict. List ord. Dict. Char That’s nice, but how is it going to solve our problem? Do-it-yourself dictionaries in Haskell 15
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 Do-it-yourself dictionaries in Haskell 16
Back to our example Suppose we have our own dictionary for Ord [Char] called ‘impl 2’ which defines (>) as: (>) : : String -> Bool (>) = x y -> (length x) > (length y) We can now explicitly pass this dictionary to a function: get. Maximum. Size : : String -> Int get. Maximum. Size {impl 2} = x y -> if x > y then (length x) else (length y) Do-it-yourself dictionaries in Haskell 17
Extending the syntax • Several attempts • What are the drawbacks ? • How can they be avoided ? Do-it-yourself dictionaries in Haskell 18
Attempt 1 Allow users to define dictionaries explicitly instance Ord [Char] where (>) [] _ = False (>) _ [] = True (>) (x: xs) (y: ys) = (x > y) && (xs > ys). . . ord. Dict. String’ = Ord. Dict { gt’ = (a b -> compare (length a) (length b) == GT), . . . } Do-it-yourself dictionaries in Haskell 19
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 Do-it-yourself dictionaries in Haskell 20
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 Do-it-yourself dictionaries in Haskell {impl 2} 21
Attempt 2 • Good things: – Implementation not visible to user – Consistent with existing syntax • Drawbacks – Unhandy when using modules Do-it-yourself dictionaries in Haskell 22
Attempt 3 Name the instance declaration impl 2 = instance Ord [Char] where (>) a b = length a > length b Capable of modifying instances in other modules Do-it-yourself dictionaries in Haskell 23
Attempt 4 Which instance declaration do we want to override ? Impl 2 overrides impl = instance Ord [Char] where (>) a b = length a > length b When no overrides statement -> default Only one default allowed, explicit or implicitly defined Do-it-yourself dictionaries in Haskell 24
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 Do-it-yourself dictionaries in Haskell 25
Formal typing / translation rules Do-it-yourself dictionaries in Haskell 26
Formal typing / translation rules • Now: – gt : : Ord a => a -> Bool • Will be written as – gt : : forall a. (ord : : Ord a). a -> Bool is an abbrevation for (a -> • But now the important part !!! • Eq a Do-it-yourself dictionaries in Haskell a -> Bool) 27
Typing / translation rules • Translation is controlled by typing A, (ord : : Ord Char ord. Dict. Char) |- e : : p ē A |- e : : (ord : : Ord Char). p ( ord. Dict. Char. ē) • In the current system, there can only be one instance with a certain type • In our system this is not the case Do-it-yourself dictionaries in Haskell 28
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. Do-it-yourself dictionaries in Haskell 29
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 Do-it-yourself dictionaries in Haskell 30
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 Do-it-yourself dictionaries in Haskell 31
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. Do-it-yourself dictionaries in Haskell 32
ca76dcb5fd373a9833054917477be741.ppt