Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Arrows

 Arrows

Class presentation

Rahul Gopinath

April 16, 2011
Tweet

More Decks by Rahul Gopinath

Other Decks in Programming

Transcript

  1. Why? || processing - Hporter Signal Processing – FRP GUI

    – Fruit Optimized Parser Combinators
  2. Invented as a means to generalize Monads. (Like Monads) comes

    from category theory. The Case for Arrows Can provide interface to true nondeterminisAc parallel computaAon. Think of both Monads and Arrows as interfaces to computaAon. They specify the general structure of a computaAon.
  3. What are Arrows Monads specifies an output type. class Monad

    m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a e.g : Maybe Kind = * ->* Arrows specifies an input and an output type. (Don't look at the definitions now. They are just to show that it takes two parameters) class Category a where idA :: a b b (>>>) :: a b c -> a c d -> a b d class Category a => Arrow a where arr :: (b -> c) -> a b c (>>>) :: a b c -> a c d -> a b d first :: a b c -> a (b,d) (c,d) second :: a b c -> a (d,b) (d,c) (***) :: a b c -> a b' c' -> a (b,b') (c,c') (&&&) :: a b c -> a b c' -> a b (c,c') e.g : functions (->) a b == a -> b Kind = *-> * -> *
  4. Q: What is the difference between Monad, Arrow and Category?

    Is there any relation between them? Category theory: A category is a mathematical structure defined as a collection of objects and associations, and obeys certain laws. A monad on a category is a functor with associated natural transformations. Haskell: It is a nice interface to structure your computations around so that very little assumptions are made. Implementation: class Category idA, (>>>) class Arrow arr, first class ArrowApply app (== Monad)
  5. What can we do with them? Create an arrow from

    a function (pure) arr:: (b->c) a b c Compose two arrows together (>>>) :: a b c -> a c d -> a b d A product (***):: a b c -> a b’ c’ ->a (b,b’) (c,c’) f ***g = first f >>> second g A fanout &&& (&&&)::a b c -> a b c’ ->a b (c,c’)
  6. More specialized operaAons First – one sided product first f

    = f *** id Second - mirror of the first second f = id *** f
  7. Some laws class Category a where idA :: a b

    b (>>>) :: a b c -> a c d ->a b d class Arrow a where arr :: (b -> c) -> a b c (>>>) :: a b c-> a c d -> a b d first :: a b c -> a (b,c) (b’,c) second ::a b c -> a (b,c) (b,c’) Product functor f x g = \(a,b) → (f a, g b) iden+ty idA >>> f = f >>> idA = f associativity (f >>> g ) >>> h = f >>> (g >>>h) functor-iden+ty pure id = idA functor-composi+on arr (g . f) = arr f >>> arr g extension first (arr f) = arr (f x id) functor first (f>>>g) = first f >>> first g exchange first f >>>arr (id x g) =arr (id x g) >>> first f unit first f >>> arr fst = arr fst >>> f associa+on first (first f)>>>arr assoc=arr assoc>>>first f
  8. Q: What happens if the axioms are not satisfied? e.g

    first? Functor : first (f>>>g) = first f >>> first g If it is not satisfied, then you will no longer be able to rely on their properties. import Control.Arrow cA w = Kleisli readFile >>> arr words >>> arr (filter (==w)) >>> arr length >>> Kleisli print cA2 w = Kleisli readFile >>> arr (words >>> (filter (==w)) >>> length) >>> Kleisli print xA = runKleisli (cA "module") "Cl.lhs" xA2 = runKleisli (cA2 "module") "Cl.lhs"
  9. Some examples. ordinary functions are an instance of arrow instance

    Arrow (->) where arr = id (>>>) = flip (.) first f = f x id we can define a state transformer as an arrow. type State z a b = (z,a) -> (z,b) instance Arrow (State z) where arr f = ST (id x f) ST f >>> ST g = ST (g . f) first (ST f) = ST (assoc . (f x id) . unassoc where unassoc (val, (state, c)) = ((val,state),c) fetch :: State z () z fetch = ST (\(s,()) -> (s,s)) store :: State z z () store = ST (\(s,s’) ->(s’,()))
  10. Arrows and Monads class Arrow a => ArrowApply a where

    app :: a (a c d, c) d Functions are an instance of ArrowApply instance ArrowApply (->) where app (f,c) = f c For any monad m, functions of type a - > m b are potential arrows newtype Kleisli m a b = K (a -> m b) instance Monad m => ArrowApply (Kleisli m) where arr f = K (\b -> return (f b)) K f >>> K g = K (\b -> f b >>= g) app = K ( \(K f, x) -> f x) Conversely ArrowApply can be used to construct a monad newtype ArrowApply a => ArrowMonad a b = M (a () b) instance ArrowApply a => Monad (ArrowMonad a) where return y = M (arr (\z -> y)) M m >>= f = M (m >>> arr (\y -> let M h = f y in (h, ())) >>> app) Hence ArrowApply == Monad All Arrows are not monads. Only those that support the ArrowApply interface (app)
  11. NotaAon import Control.Arrow addA :: Arrow a => a b

    Int -> a b Int -> a b Int addA f g = proc x -> do y <- f -< x z <- g -< x returnA -< y + z Same as addA f g = arr (\ x -> (x, x)) >>> first f >>> arr (\ (y, x) -> (x, y)) >>> first g >>> arr (\ (z, y) -> y + z) or addA f g = f &&& g >>> arr (\ (y, z) -> y + z) compare to monadic add addM a b = do x <- a y <- b return (x+y) proc () do, arrow head <- and arrow tail -<
  12. Examples. {-# LANGUAGE Arrows #-} import Control.Arrow (returnA) idA ::

    a -> a idA = proc a -> returnA -< a plusOne :: Int -> Int plusOne = proc a -> returnA -< (a+1) *Main> idA 3 3 *Main> idA "foo" "foo" *Main> plusOne 3 4 plusOne = proc a -> returnA -< (a+1) plusTwo = proc a -> plusOne -< (a+1) plusFive = proc a -> do b <- plusOne -< a c <- plusOne -< b d <- plusOne -< c e <- plusOne -< d plusOne -< e
  13. Monads and Arrows (Compare NotaAon) import Control.Arrow addA :: Arrow

    a => a b Int -> a b Int -> a b Int addA f g = proc x -> do y <- f -< x z <- g -< x returnA -< y + z Same as addA f g = arr (\ x -> (x, x)) >>> first f >>> arr (\ (y, x) -> (x, y)) >>> first g >>> arr (\ (z, y) -> y + z) or addA f g = f &&& g >>> arr (\ (y, z) -> y + z) compare to monadic add addM a b = do x <- a y <- b return (x+y)
  14. Q: Can you demonstrate this library? module Unix where import

    Control.Monad import Control.Arrow count w = (>>= print) . liftM (length . filter (==w) . words ) . readFile cM w f = do x <- readFile f y <- return $ length (filter (==w) (words x)) print y Return () xM = cM "module" "Cl.lhs" a # b = a >>> b cA w = Kleisli readFile # arr words # arr (filter (==w)) # arr length # Kleisli print cA2 w = Kleisli readFile # arr (words # (filter (==w)) # length) # Kleisli print xA = runKleisli (cA "module") "Cl.lhs" xA2 = runKleisli (cA2 "module") "Cl.lhs"