arr
(b → c) → a b c
Lift a pure function to an arrow
arr (+1) >>> arr (*2)
(>>>)
a b c → a c d → a b d
Left-to-right composition
f >>> g means f then g
(<<<)
a c d → a b c → a b d
Right-to-left composition
g <<< f means f then g
first
a b c → a (b,d) (c,d)
Apply arrow to first component of pair
first f = f *** id
second
a b c → a (d,b) (d,c)
Apply arrow to second component
second f = id *** f
(***)
a b c → a b’ c’ → a (b,b’) (c,c’)
Split input, apply both arrows in parallel
f *** g = first f >>> second g
(&&&)
a b c → a b c’ → a b (c,c’)
Fanout: duplicate input to both arrows
f &&& g produces (f x, g x)
(^>>)
(c → d) → a d e → a c e
Pre-compose with pure function
f ^>> g = arr f >>> g
(>>^)
a c d → (d → e) → a c e
Post-compose with pure function
f >>^ g = f >>> arr g
(<<^)
a d e → (c → d) → a c e
Pre-compose (right-to-left)
g <<^ f = arr f >>> g
(^<<)
(d → e) → a c d → a c e
Post-compose (right-to-left)
g ^<< f = f >>> arr g
zeroArrow
a b c
Arrow that always fails
Used for optional/failing computations
(<+>)
a b c → a b c → a b c
Try first arrow, if it fails try second
f <+> g chooses first success
left
a b c → a (Either b d) (Either c d)
Apply arrow to Left values
left f = f +++ id
right
a b c → a (Either d b) (Either d c)
Apply arrow to Right values
right f = id +++ f
(+++)
a b c → a b’ c’ → a (Either b b’) (Either c c’)
Choice between two arrows
f +++ g = left f >>> right g
(|||)
a b d → a c d → a (Either b c) d
Fanin: merge two arrows to same output
(f ||| g) (Left x) = f x
(f ||| g) (Right y) = g y
Kleisli m
newtype wrapping a → m b
Arrows from monadic functions
runKleisli :: Kleisli m a b → a → m b
Example:
readFile’ = Kleisli readFile
lines’ = arr lines
process = readFile’ >>> lines’