Slide 1

Slide 1 text

Arrows Rahul Gopinath

Slide 2

Slide 2 text

Why? || processing - Hporter Signal Processing – FRP GUI – Fruit Optimized Parser Combinators

Slide 3

Slide 3 text

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.

Slide 4

Slide 4 text

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 = *-> * -> *

Slide 5

Slide 5 text

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)

Slide 6

Slide 6 text

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’)

Slide 7

Slide 7 text

More specialized operaAons First – one sided product first f = f *** id Second - mirror of the first second f = id *** f

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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"

Slide 10

Slide 10 text

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’,()))

Slide 11

Slide 11 text

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)

Slide 12

Slide 12 text

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 -<

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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)

Slide 15

Slide 15 text

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"