recursion for the masses
play

Recursion for the Masses TCS Seminar WS19/20 Christoph Rauch Dec - PowerPoint PPT Presentation

Recursion for the Masses Recursion for the Masses TCS Seminar WS19/20 Christoph Rauch Dec 10, 2019 Recursion for the Masses Introduction of Recursion to Students Early Stage (FAU) students are more or less expected to "know" what


  1. Recursion for the Masses Recursion for the Masses TCS Seminar WS19/20 Christoph Rauch Dec 10, 2019

  2. Recursion for the Masses Introduction of Recursion to Students Early Stage (FAU) students are more or less expected to "know" what recursion is no definition at all in maths classes "Java can do it" plus a definition of what a recursive definition looks like in Java in GDA (now AuD) tail recursion, mutual recursion, divide & conquer similarly "Haskell can do it" in PFP literally recommended to use iteration whenever possible nowadays, students are blessed with ThProg!

  3. Recursion for the Masses First Real Contact Theory of Programming We learn that . . . (inductive) data types are initial algebras to functors initiality provides unique solutions to recursive equations of a certain form ; the "recursion scheme" of folds (and, in fact, the more general primitive recursion ) there’s a dual concept (namely final coalgebras) for coinductive data first examples of structured recursion not the end of the line!

  4. ↔ Recursion for the Masses Recursion Schemes Recursion Schemes folds (tear down a structure) unfolds (build up a structure) algebra f a → Fix f → a coalgebra f a → a → Fix f cata morphism ana morphism f a → a a → f a g eneralized prepro morphism* postpro morphism* (m f ↝ f m) → ( α → f (m β )) … after applying a NatTrans … before applying a NatTrans (f a → a) → (f ↝ f) (a → f a) → (f ↝ f) g eneralized para morphism* apo morphism* (f w ↝ w f) → (f (w α ) → β ) … with primitive recursion … returning a branch or single level f (Fix f ⨯ a) → a a → f (Fix f ∨ a) zygo morphism* g apo morphism … with a helper function (f b → b) → (f (b ⨯ a) → a) (b → f b) → (a → f (b ∨ a)) histo morphism futu morphism g histo morphism g futu morphism … with prev. answers it has given … multiple levels at a time (f h ↝ h f) → (f (w a) → a) (h f ↝ f h) → (a → f (m a)) f (Cofree f a) → a a → f (Free f a) refolds (build up then tear down a structure) algebra g b → (f ↝ g) → coalgebra f a → a → b hylo morphism others cata; ana g eneralized dyna morphism codyna morphism synchro morphism apply the generalizations for both histo; ana cata; futu the relevant fold and unfold chrono morphism ??? histo; futu exo morphism Elgot algebra coElgot algebra … may short-circuit while building … may short-circuit while tearing ??? cata; a → b ∨ f a a ⨯ g b → b; ana mutu morphism reunfolds (tear down then build up a structure) coalgebra g b → (a → b) → algebra f a → Fix f → Fix g … can refer to each other’s results meta morphism g eneralized (f (a ⨯ b) → a) → (f (a ⨯ b) → b) ana; cata apply … both … [un]fold Stolen from Edward Kmett’s http://comonad.com/reader/ 2009/recursion-schemes/ These can be combined in various ways. For example, a “zygohistomorphic * This gives rise to a family of related recursion schemes, prepromorphism” combines the zygo, histo, and prepro aspects into a modeled in recursion-schemes with distributive law signature like (f b → b) → (f ↝ f) → (f (w (b ⨯ a)) → a) → Fix f → a combinators

  5. Recursion for the Masses Recursion Schemes Ban General Recursion using general recursion carelessly = chaos (structured programming : goto) as (recursion schemes : general recursion) [Meijer et al. 2006] Use Schemes Instead enjoy many desirable properties (e.g. fusion, compositionality) expressive, generic, concise

  6. Recursion for the Masses Recursion Schemes Ban General Recursion using general recursion carelessly = chaos (structured programming : goto) as (recursion schemes : general recursion) [Meijer et al. 2006] Use Schemes Instead enjoy many desirable properties (e.g. fusion, compositionality) expressive, generic, concise a little bit scary but knowing about them can help make code more efficient and safe

  7. Recursion for the Masses Example: Zygomorphism I Task: write function with property f [v,w,x,y,z] = v - (w + (x - (y + z))) first attempt: lengthEven :: [a] -> Bool lengthEven = even . length f [] = 0 f (x:xs) = if lengthEven xs then x - f xs else x + f xs

  8. Recursion for the Masses Example: Zygomorphism II First, notice that the rhs of f needs access to f xs as well as x and xs there is a scheme for that! paramorphisms – just a fancy name for primitive recursion on inductive data types: para :: (a -> [a] -> b -> b) -> b -> [a] -> b para f z [] = z para f z (x:xs) = f x xs (para f z xs) f = para (\x xs ac -> if lengthEven xs then x - ac else x + ac) 0

  9. Recursion for the Masses Example: Zygomorphism III Now . . . lengthEven is called in each recursive call quadratic algorithm but: both lengthEven and para are catamorphisms (folds): lengthEven = cata (\x p -> not p) True para' f z = snd . cata (\x (xs, acc) -> (x:xs, f x xs acc)) ([], z)

  10. Recursion for the Masses Example: Zygomorphism IV Finally . . . there is a scheme for that! running two folds in parallel, one of which depends on the result of the other, can be done by way of a zygomorphism : zygo :: (a -> b -> b) -> (a -> b -> c -> c) -> b -> c -> [a] -> c zygo f g z e = snd . cata (\x (p, q) -> (f x p, g x p q)) (z, e) f = zygo (\x p -> not p) (\x e t -> if e then x - t else x + t) True 0

  11. Recursion for the Masses Duals and Combinations So far . . . we’ve only used initial algebras there are duals for final coalgebras, of course however, there are also schemes combining the two how is that even possible?

  12. Recursion for the Masses Data = Codata in Hask I Turning a Blind Eye Haskell allows partial functions blurred distinction between data types and codata types allows people to be lazy (no pun intended) "The usual style is to write as if everything is inductive, and if it still works on infinite data, to pat ourselves on the back for using Haskell rather than ML." – Conor McBride

  13. Recursion for the Masses Data = Codata in Hask II Hask , the category of Haskell types and functions, is algebraically compact basically CPO initial algebras and final coalgebras coincide opens up a cheap way to develop more recursion schemes but also necessitates some arbitrary choices and a nasty proof theory

  14. Recursion for the Masses Example: Hylomorphism I The scheme given an F -algebra a and a coalgebra c , morphisms satisfying the equation h = a ◦ Fh ◦ c the so-called hylo scheme morphisms between any two types! The predicament however, unique solutions are not guaranteed, even in Haskell but, canonical solutions exist: hylo :: (Functor f) => (f a -> a) -> (c -> f c) -> c -> a hylo alg coalg = cata alg . ana coalg

  15. Recursion for the Masses Example: Hylomorphism II The example: Merge sort Algorithm 1 recursively divide a list into smaller lists 2 when the recursive calls return, merge the resulting sorted lists into a bigger sorted list Implementation divide-and-conquer algorithms lend themselves to the hylo scheme the functor f models the shape of the recursive calls; here: a binary tree an anamorphism for a coalgebra split builds up the tree and a catamorphism for an algebra merge tears it down again

  16. Recursion for the Masses Merge Sort import Data.List import Data.Functor.Foldable (hylo) import qualified Data.List.Ordered as O data Tree a b = Empty | Leaf a | Node b b deriving Functor split [] = Empty split [x] = Leaf x split xs = let (l, r) = splitAt (length xs `div` 2) xs in Node l r merge Empty = [] merge (Leaf x) = [x] merge (Node l r) = O.merge l r mergesort :: Ord a => [a] -> [a] mergesort = hylo merge split

  17. Recursion for the Masses Generalisations Monads and Comonads recall: all schemes work for arbitrary functors (and their associated data types) but there’s no self-respecting Haskell program without monads recursion-schemes takes that into consideration schemes can be lifted to the (co)Kleisli category of a (co)Monad but: requires distributive laws Distributive Laws given monad M and functor F , natural transformation MF → FM dually for comonads recursion-schemes offers basic laws and combinators to build new ones

  18. Recursion for the Masses Monadic Iteration Performing Side-Effects Repeatedly Elgot monad: monad m with iteration operator of signature ( a → m ( b + a )) → ( a → mb ) satisfying certain natural axioms every Monad in Hask is Elgot (by enrichment of Kleisli over CPO) Haskell’s loopM has the type signature above more useful/problematic in more specific settings (e.g. languages without general recursion, with hard-wired effects in the background)

  19. Recursion for the Masses Moving to Total Programming Totality enables distinction between data and codata removes arbitrary choices in terms of strictness simplifies the proof theory (e.g. e − e = 0 is not always true in Haskell, since e might be ‘ ⊥ ‘) but some recursion schemes are no longer applicable Monads are no longer automatically Elgot we need to ensure productivity in (co)recursive definitions of codata

  20. Recursion for the Masses Catamorphisms in Agda I Agda dependently typed programming language totality ensured by (quite restrictive) positivity and termination checkers General Definition in Haskell, data Mu f = In (f (Mu f)) is valid for any functor Agda’s positivity checker rejects this however, initial algebras for polynomial functors can be defined generically data mu_ (F : Functor) : Set where <_> : [ F ] (mu F) -> mu F

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend