Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are Arrows a true generalization of functions?

Tags:

haskell

arrows

Arrows are often described as generalization of functions (statically generated functions only, i.e. there's no support for partial application / closures). However, at least looking at Arrows as they are modeled in Haskell, I can't see how they can generalize functions of multiple arguments that return a single result (a result that in general might not be a tuple). I'm trying to envision how using just the arrows interface one could arrive at a composition of arrows that produces a single result that in general might not be a tuple. Is there a way to do this or is this a deliberate limitation on the power of the Arrow type?

From what I understand arrows provide the ability to compose static (possibly parallel) pipelines but they can't 'fold' the tuples of outputs into a single final result. Am wrong or I missing something?

like image 832
Dr DR Avatar asked Apr 14 '15 00:04

Dr DR


1 Answers

I can't see how they can generalize functions of multiple arguments that return a single result

Just let the input type be a tuple, and the output a plain value. For example, take the arrow

plus :: a (num, num) num
let plus = arr (\(a, b) -> a + b) -- arr (uncurry (+))

Alternatively, you can take "nested arrows" - a curried function with multiple arguments is nothing but a function that returns a function. So we'd have an arrow whose result is another arrow:

plus :: a num (a num num)
let plus = arr (arr . (+))

and to use that, we need an ArrowApply instance. First, you'd combine the arrow with an other arrow that creates the second argument from your input

plusWithIncrement :: a num (a num num, num)
let plusWithIncrement = plus &&& arr (+1)

and then you could run that

plusWithIncrement >>> app :: a num num

(which is an overcomplicated way of writing arr (\x -> x + (x+1)))

like image 74
Bergi Avatar answered Sep 28 '22 06:09

Bergi