Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the use of Applicative/Monad instances for Sum and Product?

My understanding of Sum and Product newtypes is that they serve as monoidial wrappers for numeric types. I would understand Functor instance on them, but why there are also Applicative, Monad any many other seemingly useless instances? I understand that they are mathemathically OK (isomorphic to Identity modad, right?) But what is the use case? If there is an Applicative Sum instance, for example, I would expect to encounter a value of type Sum (a -> b) somewhere. I can't imagine where this could possibly be useful.

like image 436
user1747134 Avatar asked Sep 27 '16 15:09

user1747134


2 Answers

Such instances are convenient for lifting arbitrary functions to work on things that happen to currently be living inside a Sum or Product. For example, one might imagine wanting to do some bitwise operations on something that is nevertheless more convenient in a Sum than bare; then liftA2 (.&.) :: Sum Int -> Sum Int -> Sum Int (for example).

One could also provide this operation by giving a Bits instance for Sum, but generalizing that technique would require the implementors of Sum to predict every operation one might ever want to do, which seems like a tall order. Providing Applicative and Monad instances give a once-and-for-all translation for users to lift any function they like -- including ones the implementors of Sum did not predict being useful.

like image 177
Daniel Wagner Avatar answered Nov 16 '22 01:11

Daniel Wagner


Values like this typically result from partial application of binary operators. Assuming Functor and Applicative instances like

import Control.Applicative
import Data.Monoid

instance Functor Sum where
    fmap f (Sum x) = Sum (f x)

instance Applicative Sum where
    pure = Sum
    (Sum f) <*> (Sum x) = Sum (f x)

then you can see how a value of Sum (a -> b) would arise.

> :t (*) <$> (Sum 5)
(*) <$> (Sum 5) :: Num a => Sum (a -> a)

> (*) <$> (Sum 5) <*> (Sum 10)
Sum {getSum = 50}
like image 20
chepner Avatar answered Nov 16 '22 00:11

chepner