
On 2015-12-09 22:20, Tom Ellis wrote:
while learning about all the type classes and their relationships I came across something I found weird. If I understand it correctly, banana brackets where originally developed for Applicatives. The intent was to enable us to write something like I don't think Arrow banana brackets are related to these Applicative (or "Idiom") brackets.
Let me try to convince you. ;) Actually I have no idea if there is a historical relationship, but there is definitely a semantic one. Consider this: 1) An alternative definition of Applicative is as a monoidal, with the operation comma :: f a -> f b -> f (a,b) "comma" is connected with (<*>) through the Functor superclass. It's typically named (**), but I'll use a prefix version. 2) Every arrow a b c is an applicative (a b) c, because comma = (&&&). Conversely, every applicative that is polymorphic over some "internal" variable is automatically an arrow, through (&&&) = comma. 3) Let's rename (&&&) to "andA". It's trivial to think of "comma" and "andA" as the special versions "comma2" and "andA2" of more general forms commaN and andAn for all natural numbers n. The equivalence of both functions extends naturally for all n. (N.B.: comma0/andA0 and comma1/andA1 are very interesting functions and one of the reasons I left out all the stuff from Pointed/CoPointed/Unit. The other reason is simplification.) 4) An idiom bracket (| f x1 x2 ... xn |) translates very roughly to liftA (uncurryN f) (commaN x1 x2 ... xn) while a banana bracket (| f x1 x2 ... xn |) translates very roughly to liftA' (uncurryN f) (andAn x1 x2 ... xn) And as commaN and andAn are equivalent, the relation should be obvious now. Of course that's a very very rough sketch without any proofs, without looking at the wrappers, and with slightly modified semantics in the first argument. Still, I'm convinced both are (almost) the same. But then I might be overlooking something important...