Reputation: 34081
I am trying to understand the tuple applicative. When I look at information in prelude about tuple, it says:
instance (Monoid a, Monoid b) => Monoid (a, b)
instance Monoid a => Applicative ((,) a)
What does ((,) a)
mean? It does not look like a tuple.
I have following example:
Prelude Data.Monoid> ((Sum 2), (+2)) <*> ((Sum 45), 8)
(Sum {getSum = 47},10)
The first argument in the tuple is an instance of monoid and the second it is just a function application. But how does the signature ((,) a)
match the example above?
Upvotes: 1
Views: 1452
Reputation: 120711
I prefer to write the instance as a tuple section (which is not actually legal Haskell, but gets the point across:
instance Monoid a => Applicative (a,)
... and before discussing that, consider
instance Functor (a,)
What this does is just: for any left-hand element (of type a
), map over whichever right-hand argument there is. I.e.
fmap :: (b -> c) -> (a,b) -> (a,c)
One might at this point wonder why we have (a,)
and not (,a)
. Well, mathematically speaking, the following is just as valid:
instance Functor (,a)
fmap :: (a -> b) -> (a,c) -> (b,c)
...however that can't be defined because (a,b)
is in fact syntactic sugar for (,) a b
, i.e. the tuple-type-constructor (,)
applied first to the a
type and then to the b
type. Now, in instance Functor (a,)
, we simply leave the b
open to be fmapped over, hence
instance Functor ((,) a)
But it's not possible to _only apply the b
argument, while leaving a
open – that would require a sort of type-level lambda
“instance Functor (\b -> (a,b))”
which is not supported.
Now as to Applicative
– that just extends the (a,)
functor to also support combinations of multiple tuples, provided there's already a natural way to combine the a
elements – that's what the Monoid
instance offers. This is better known as the Writer monad, because it's well suited for generating a “operations log” along with the actual computation results:
Prelude> ("4+", (4+)) <*> ("10",10)
("4+10",14)
Upvotes: 3