user2879704
user2879704

Reputation:

Control.Category, what does >>> and <<< mean?

I am following this blog, to write a simple http server in haskell,

Usage of >>> is not clear to me. What does this code snippet do?

handleHttpConnection r c = runKleisli
    (receiveRequest >>> handleRequest r >>> handleResponse) c >>
    close c

Similary on this link, i am seeing <<<

let h =     arr (++ "!")
          <<< arr foo
          <<< Kleisli bar
          <<< arr id

What does <<< and >>> do? (Hackage document is very concise and couldn't get much out of it.)

Upvotes: 16

Views: 1178

Answers (1)

leftaroundabout
leftaroundabout

Reputation: 120741

As Hackage and/or Hoogle will tell you,

(>>>) :: Category k => a`k`b  -> b`k`c  -> a`k`c
(<<<) :: Category k => b`k`c  -> a`k`b  -> a`k`c

Observe that the latter is actually the same as

(.)   :: Category k => b`k`c  -> a`k`b  -> a`k`c

or, in its Prelude form, specialised to the Hask category of functions,

(.)   ::               (b->c) -> (a->b) -> (a->c)

So, <<< and >>> simply compose functions, or more generally morphisms/arrows.

<<< composes in the same direction as the familiar ., while >>> flips the arguments so that “data flows from left to right”.


Now, what arrow composition means, for categories other than Hask, depends of course on the category. Kleisli IO is an easy to understand example: say we have a pure function

pipe :: Double -> String
pipe = show . sqrt . (+2) . abs

As I said, this can also be written

pipe = abs >>> (+2) >>> sqrt >>> show

Now, if you want to add primitive IO logging (like you might in an imperative language), you can introduce

type (-|>) = Kleisli IO

abs', add2', sqrt' :: Num a => a -|> a
show' :: Show a => a -|> String

abs'  = Kleisli $ \x -> do putStrLn ("Absolute of "++show x++"...")
                           return $ abs x
add2' = Kleisli $ \x -> do putStrLn ("Add 2 to "++show x++"...")
                           return $ x + 2
sqrt' = Kleisli $ \x -> do putStrLn ("Square root of "++show x++"...")
                           return $ sqrt x
show' = Kleisli $ \x -> do putStrLn ("Show "++show x++"...")
                           return $ show x

With that, you can define

pipe' :: Double -|> String

in exactly the same way as before, i.e.

pipe' = abs' >>> add2' >>> sqrt' >>> show'

But you'll now get the intermediate results printed out as a side-effect.

Upvotes: 22

Related Questions