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

Popular posts from this blog

android - Spacing between the stars of a rating bar? -

aspxgridview - Devexpress grid - header filter does not work if column is initially hidden -

c# - How to execute a particular part of code asynchronously in a class -