Presentation is loading. Please wait.

Presentation is loading. Please wait.

Do-it-yourself dictionaries in Haskell1 Ingmar Brouns & Lukas Spee.

Similar presentations


Presentation on theme: "Do-it-yourself dictionaries in Haskell1 Ingmar Brouns & Lukas Spee."— Presentation transcript:

1 Do-it-yourself dictionaries in Haskell1 Ingmar Brouns & Lukas Spee

2 Do-it-yourself dictionaries in Haskell2 Introduction Extending the Haskell class system Allowing multiple implementations for one instance of a class declaration

3 Do-it-yourself dictionaries in Haskell3 Introduction – examples (1) An example from the Java world: Equality: based on reference equivalence or member field value equivalence?

4 Do-it-yourself dictionaries in Haskell4 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

5 Do-it-yourself dictionaries in Haskell5 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 ?

6 Do-it-yourself dictionaries in Haskell6 Current Class System Define class & instance declarations Translation, to a core-Haskell variant without overloading, by preprocessor How does this translation work ?

7 Do-it-yourself dictionaries in Haskell7 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

8 Do-it-yourself dictionaries in Haskell8 Translation - example class Eq a => Ord a where (>) :: a -> a -> Bool data OrdDict a = OrdDict { gt’ :: a -> a -> Bool, …} will be translated to:

9 Do-it-yourself dictionaries in Haskell9 Translation - example instance Ord Char where (>) = primitiveGT ordDictChar :: OrdDict Char ordDictChar = OrdDict { gt’ = primitiveGT, …} will be translated to:

10 Do-it-yourself dictionaries in Haskell10 Translation - example foo :: Ord a => a -> a -> Bool foo = \x y -> x > y foo :: OrdDict a -> a -> a -> Bool foo = \ordDict x y -> gt’ ordDict x y So, in fact, dictionaries are implicit parameters that ‘control’ the overloading will be translated to:

11 Do-it-yourself dictionaries in Haskell11 Translation - example Which 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’

12 Do-it-yourself dictionaries in Haskell12 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 ?

13 Do-it-yourself dictionaries in Haskell13 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)

14 Do-it-yourself dictionaries in Haskell14 A dictionary for Ord [a] ordDictList :: OrdDict a -> OrdDict [a] ordDictList ordD = OrdDict (ordList ordD) ordList :: OrdDict a -> [a] -> [a] -> Bool ordList ordDict (x:xs) [] = True ordList ordDict [] (y:ys) = False ordList ordDict (x:xs) (y:ys) = gt’ ordDict x y && gt’ (ord ordDict) xs ys Please remember this for one more slide

15 Do-it-yourself dictionaries in Haskell15 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?

16 Do-it-yourself dictionaries in Haskell16 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

17 Do-it-yourself dictionaries in Haskell17 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:

18 Do-it-yourself dictionaries in Haskell18 Extending the syntax Several attempts What are the drawbacks ? How can they be avoided ?

19 Do-it-yourself dictionaries in Haskell19 Attempt 1 Allow users to define dictionaries explicitly instance Ord [Char] where (>) [] _ = False (>) _ [] = True (>) (x:xs) (y:ys) = (x > y) && (xs > ys)... ordDictString’ = OrdDict { gt’ = (\a b -> compare (length a) (length b) == GT),...}

20 Do-it-yourself dictionaries in Haskell20 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

21 Do-it-yourself dictionaries in Haskell21 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}

22 Do-it-yourself dictionaries in Haskell22 Attempt 2 Good things: –Implementation not visible to user –Consistent with existing syntax Drawbacks –Unhandy when using modules

23 Do-it-yourself dictionaries in Haskell23 Attempt 3 Name the instance declaration impl2 = instance Ord [Char] where (>) a b = length a > length b Capable of modifying instances in other modules

24 Do-it-yourself dictionaries in Haskell24 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 -> default Only one default allowed, explicit or implicitly defined

25 Do-it-yourself dictionaries in Haskell25 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

26 Do-it-yourself dictionaries in Haskell26 Formal typing / translation rules

27 Do-it-yourself dictionaries in Haskell27 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 !!!

28 Do-it-yourself dictionaries in Haskell28 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

29 Do-it-yourself dictionaries in Haskell29 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.

30 Do-it-yourself dictionaries in Haskell30 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

31 Do-it-yourself dictionaries in Haskell31 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

32 Do-it-yourself dictionaries in Haskell32 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.


Download ppt "Do-it-yourself dictionaries in Haskell1 Ingmar Brouns & Lukas Spee."

Similar presentations


Ads by Google