haskell - What are arrows, and how can I use them? -
i tried learn meaning of arrows, didn't understand them.
i used wikibooks tutorial. think wikibook's problem seems written understands topic.
can explain arrows , how can use them?
i don't know tutorial, think it's easiest understand arrows if @ concrete examples. biggest problem had learning how use arrows none of tutorials or examples show how use arrows, how compose them. so, in mind, here's mini-tutorial. i'll examine 2 different arrows: functions , user-defined arrow type myarr.
-- type representing computation data myarr b c = myarr (b -> (c,myarr b c)) 1) arrow calculation input of specified type output of specified type. arrow typeclass takes 3 type arguments: arrow type, input type, , output type. looking @ instance head arrow instances find:
instance arrow (->) b c instance arrow myarr b c the arrow (either (->) or myarr) abstraction of computation.
for function b -> c, b input , c output.
myarr b c, b input , c output.
2) run arrow computation, use function specific arrow type. functions apply function argument. other arrows, there needs separate function (just runidentity, runstate, etc. monads).
-- run function arrow runf :: (b -> c) -> b -> c runf = id -- run myarr arrow, discarding remaining computation runmyarr :: myarr b c -> b -> c runmyarr (myarr step) = fst . step 3) arrows used process list of inputs. functions these can done in parallel, arrows output @ given step depends upon previous inputs (e.g. keeping running total of inputs).
-- run function arrow on multiple inputs runflist :: (b -> c) -> [b] -> [c] runflist f = map f -- run myarr on multiple inputs. -- each step of computation gives next step use runmyarrlist :: myarr b c -> [b] -> [c] runmyarrlist _ [] = [] runmyarrlist (myarr step) (b:bs) = let (this, step') = step b in : runmyarrlist step' bs this 1 reason arrows useful. provide computation model can implicitly make use of state without ever exposing state programmer. programmer can use arrowized computations , combine them create sophisticated systems.
here's myarr keeps count of number of inputs has received:
-- count number of inputs received: count :: myarr b int count = count' 0 count' n = myarr (\_ -> (n+1, count' (n+1))) now function runmyarrlist count take list length n input , return list of ints 1 n.
note still haven't used "arrow" functions, either arrow class methods or functions written in terms of them.
4) of code above specific each arrow instance[1]. in control.arrow (and control.category) composing arrows make new arrows. if pretend category part of arrow instead of separate class:
-- combine 2 arrows in sequence >>> :: arrow => b c -> c d -> b d -- function arrow instance -- >>> :: (b -> c) -> (c -> d) -> (b -> d) -- flip (.) -- myarr instance -- >>> :: myarr b c -> myarr c d -> myarr b d the >>> function takes 2 arrows , uses output of first input second.
here's operator, commonly called "fanout":
-- &&& applies 2 arrows single input in parallel &&& :: arrow => b c -> b c' -> b (c,c') -- function instance type -- &&& :: (b -> c) -> (b -> c') -> (b -> (c,c')) -- myarr instance type -- &&& :: myarr b c -> myarr b c' -> myarr b (c,c') -- first , second omitted brevity, see accepted answer kennytm's link -- further details. since control.arrow provides means combine computations, here's 1 example:
-- function that, given input n, returns "n+1" , "n*2" calc1 :: int -> (int,int) calc1 = (+1) &&& (*2) i've found functions calc1 useful in complicated folds, or functions operate on pointers example.
the monad type class provides means combine monadic computations single new monadic computation using >>= function. similarly, arrow class provides means combine arrowized computations single new arrowized computation using few primitive functions (first, arr, , ***, >>> , id control.category). similar monads, question of "what arrow do?" can't answered. depends on arrow.
unfortunately don't know of many examples of arrow instances in wild. functions , frp seem common applications. hxt other significant usage comes mind.
[1] except count. it's possible write count function same thing instance of arrowloop.
Comments
Post a Comment