lecture 14 foldables and traversables
play

Lecture 14. Foldables and traversables Functional Programming - PowerPoint PPT Presentation

Lecture 14. Foldables and traversables Functional Programming 2019/20 Matthijs Vkr [ Faculty of Science Information and Computing Sciences] 0 Goals How do we calculate summaries of data structures other than lists? Learn about


  1. Lecture 14. Foldables and traversables Functional Programming 2019/20 Matthijs Vákár [ Faculty of Science Information and Computing Sciences] 0

  2. Goals ▶ How do we calculate summaries of data structures other than lists? ▶ Learn about Monoid and Foldable type classes ▶ How do we map impure functions over data structures? ▶ Learn about Applicative and Traversable type classes ▶ See some examples of monadic and applicative code in action. Chapter 14 from Hutton’s book [ Faculty of Science Information and Computing Sciences] 1

  3. data Tree a = Leaf | Node (Tree a) a (Tree a) data Rose a = RLeaf | RNode a [Rose a] data Expr x = Var x | Val Int | Add (Expr x) (Expr x) Our three example data types for today Binary trees: Rose trees: ASTs: [ Faculty of Science Information and Computing Sciences] 2

  4. Linear summaries: Monoids and Foldables [ Faculty of Science Information and Computing Sciences] 3

  5. Summaries to calculate ▶ Sums, products of entries ▶ And/or of entries ▶ Used variables ▶ Composition of all functions in data structure ▶ Parity of Booleans in data structure Monoids and folds abstract the idea of combining elements in a well-behaved way! [ Faculty of Science Information and Computing Sciences] 4

  6. class Monoid m where mempty mappend :: m -> m -> m mconcat :: [m] -> m mconcat = foldr mappend mempty Monoids Some types have an intrinsic notion of combination ▶ We already hinted at it when describing folds ▶ Monoids provide an associative binary operation with an identity element :: m [ Faculty of Science Information and Computing Sciences] 5

  7. mempty instance Monoid [t] where = [] -- empty list mappend = (++) -- concatenation mconcat = concat Monoids: example Lists [T] are monoids regardless of their contained type T The simplest monoids in a sense (jargon: free monoids) [ Faculty of Science Information and Computing Sciences] 6

  8. mempty <> y = y -- left identity x <> mempty = x -- right identity (x <> y) <> z = x <> (y <> z) -- associativity Monoid laws Monoids capture well-behaved notion of combination, respecting these laws: We write mappend infjx as <> . Do these remind of you anything? [ Faculty of Science Information and Computing Sciences] 7

  9. Some examples of monoids Can you come up with some examples of monoids? [ Faculty of Science Information and Computing Sciences] 8

  10. Note that monoids may be non-commmutative, so that foldl :: (b -> a -> b) -> b -> [a] -> b foldr :: (a -> b -> b) -> b -> [a] -> b foldr mappend mempty = foldl mappend mempty foldr mappend mempty /= foldr (flip mappend) mempty Folds and Monoids Recall, folding on lists: We have seen, because of associativity and identity laws: for any monoid! [ Faculty of Science Information and Computing Sciences] 9

  11. foldl :: (b -> a -> b) -> b -> [a] -> b foldr :: (a -> b -> b) -> b -> [a] -> b foldr mappend mempty = foldl mappend mempty foldr mappend mempty /= foldr (flip mappend) mempty Folds and Monoids Recall, folding on lists: We have seen, because of associativity and identity laws: for any monoid! Note that monoids may be non-commmutative, so that [ Faculty of Science Information and Computing Sciences] 9

  12. foldr :: (a -> b -> b) -> b -> [a] -> b foldMap :: Monoid m => (a -> m) -> [a] -> m Generalizing foldr? (a -> b -> b) -> [a] -> b -> b (a -> End b ) -> [a] -> End b Does this buy us anything? [ Faculty of Science Information and Computing Sciences] 10

  13. foldr :: (a -> b -> b) -> b -> t a -> b foldMap :: Monoid m => (a -> m) -> t a -> m Foldables Want: or for some other container type t . t had better be a functor… [ Faculty of Science Information and Computing Sciences] 11

  14. class Functor t => Foldable t where foldr op i = ??? foldMap :: Monoid m => (a -> m) -> t a -> m foldMap f = ??? toList :: t a -> [a] fold :: Monoid m => t m -> m fold = ??? Foldables Data structure we can fold over, like lists: foldr :: (a -> b -> b) -> b -> t a -> b toList = ??? [ Faculty of Science Information and Computing Sciences] 12

  15. class Functor t => Foldable t where foldr op i = foldr op i . toList foldMap :: Monoid m => (a -> m) -> t a -> m foldMap f = mconcat . map f . toList toList :: t a -> [a] fold :: Monoid m => t m -> m fold = foldMap id Foldables Data structure we can fold over, like lists: foldr :: (a -> b -> b) -> b -> t a -> b toList = foldr (:) [] In essence, a data type that we can linearize to a list… [ Faculty of Science Information and Computing Sciences] 13

  16. Some examples Let’s implement Foldable for Tree , Rose and Expr ! See how they solve our initial problem! [ Faculty of Science Information and Computing Sciences] 14

  17. Mapping Impure Functions: Applicatives and Traversables [ Faculty of Science Information and Computing Sciences] 15

  18. Mapping impure functions ▶ A stateful walk of a tree ▶ A walking a rose tree while performing IO ▶ Trying to evaluate an expression while accumulating errors ▶ Idea: keep shape of data structure; replace entries using impure function; accumulate side efgects on the outside Applicatives and traversals abstract the idea of mapping impure functions in a well-behaved way! [ Faculty of Science Information and Computing Sciences] 16

  19. class Functor f => Applicative f where class Functor f where pure (<*>) :: f (a -> b) -> f a -> f b class Applicative f => Monad f where return :: a -> f a -- equals Applicative's pure (>>=) :: f a -> (a -> f b) -> f b The functor - applicative - monad hierarchy fmap :: (a -> b) -> f a -> f b :: a -> f a [ Faculty of Science Information and Computing Sciences] 17

  20. af <*> ax = do f <- af pure = return return (f x) Recall: Applicatives from Monads Every monad induces an applicative x <- ax But not every applicative arises that way! [ Faculty of Science Information and Computing Sciences] 18

  21. Why not from a monad? (Error m1) <*> (Error m2) = Error (m1 <> m2) = OK (f a) <*> (OK a) (OK f) <*> (Error m2) = Error m2 (OK f) = Error m1 (Error m1) <*> (OK a) = OK pure instance Monoid m => Applicative (Error m) where data Error m a = Error m | OK a Example: Error Accumulation Example of Applicative that does not come from Monad How is Error m a functor? An applicative? [ Faculty of Science Information and Computing Sciences] 19

  22. = OK (OK f) = OK (f a) data Error m a = Error m | OK a instance Monoid m => Applicative (Error m) where pure <*> (OK a) (Error m1) <*> (Error m2) = Error (m1 <> m2) (Error m1) <*> (OK a) = Error m1 (OK f) <*> (Error m2) = Error m2 Example: Error Accumulation Example of Applicative that does not come from Monad How is Error m a functor? An applicative? Why not from a monad? [ Faculty of Science Information and Computing Sciences] 19

  23. class Foldable t => Traversable t where (a -> f b) -> t a -> f (t b) traverse g ta = ??? sequenceA :: Applicative f => t (f a) -> f (t a) sequenceA = ??? Traversables Data structure we can traverse/walk: traverse :: Applicative f => Think of traverse as a map over t using an impure function :: a -> f b [ Faculty of Science Information and Computing Sciences] 20

  24. class Foldable t => Traversable t where (a -> f b) -> t a -> f (t b) traverse g ta = sequenceA (fmap g ta) sequenceA :: Applicative f => t (f a) -> f (t a) sequenceA = traverse id Traversables Data structure we can traverse/walk: traverse :: Applicative f => Think of traverse as a map over t using an impure function :: a -> f b [ Faculty of Science Information and Computing Sciences] 21

  25. Some examples Let’s implement Foldable for Tree , Rose and Expr ! [ Faculty of Science Information and Computing Sciences] 22

  26. Traversals are impure maps: instance Monad Identity' where newtype Identity' a = Identity' {runIdentity' :: a} return x = Identity' x = f (runIdentity' x) fmap :: Traversable t => (a -> b) -> t a -> t b fmap == runIdentity . traverse (Identity . f) Traversing with the Identity Applicative We have the identity monad x >>= f [ Faculty of Science Information and Computing Sciences] 23

  27. instance Monad Identity' where newtype Identity' a = Identity' {runIdentity' :: a} return x = Identity' x = f (runIdentity' x) fmap :: Traversable t => (a -> b) -> t a -> t b fmap == runIdentity . traverse (Identity . f) Traversing with the Identity Applicative We have the identity monad x >>= f Traversals are impure maps: [ Faculty of Science Information and Computing Sciences] 23

  28. Relating Monoids and Applicatives, Folds and Traversals [ Faculty of Science Information and Computing Sciences] 24

  29. Claim: traversing with Const is the same as folding: instance Monoid m => Applicative (Const m) where newtype Const a b = Const { getConst :: a } pure _ = Const mempty (<*>) (Const f) (Const b) = Const (f <> b) foldMap :: (Traversable t, Monoid m) => (a -> m) -> t a -> m foldMap f = getConst . sequenceA . fmap (Const . f) Phantom Types: All Monoids Are Applicatives Introduce fake type dependency: [ Faculty of Science Information and Computing Sciences] 25

Recommend


More recommend