I've just found Const
in the documentation of Control.Applicative
, but I have a hard time working out where this is useful, over just using Monoid
directly.
What am I missing?
Functor in Haskell is a kind of functional representation of different Types which can be mapped over. It is a high level concept of implementing polymorphism. According to Haskell developers, all the Types such as List, Map, Tree, etc. are the instance of the Haskell Functor.
In Haskell, an applicative is a parametrized type that we think of as being a container for data of that type plus two methods pure and <*> . Consider a parametrized type f a . The pure method for an applicative of type f has type. pure :: a -> f a. and can be thought of as bringing values into the applicative.
Another simple example of a functor is the Maybe type. This object can contain a value of a particular type as Just , or it is Nothing (like a null value).
It's merely an infix synonym for fmap , so you can write e.g. Prelude> (*2) <$> [1.. 3] [2,4,6] Prelude> show <$> Just 11 Just "11" Like most infix functions, it is not built-in syntax, just a function definition. But functors are such a fundamental tool that <$> is found pretty much everywhere.
It's rather useful when combined with Traversable
.
getConst . traverse Const :: (Monoid a, Traversable f) => f a -> a
That's the general recipe for glomming a bunch of stuff together. It was one of the use cases which convinced me that it was worth separating Applicative
from Monad
. I needed stuff like generalized elem
elem :: Eq x => x -> Term x -> Bool
to do occur-checking for a Traversable Term
parametrized by the representation of free variables. I kept changing the representation of Term
and I was fed up modifying a zillion traversal functions, some of which were doing accumulations, rather than effectful mapping. I was glad to find an abstraction which covered both.
It's useful when you have a function or data structure that works for all (Applicative
) Functor
s, and wish to reuse it in a degenerate sense. It's analogous to passing in const
or id
to functions that work given arbitrary functions.
Van Laarhoven lenses are defined in terms of arbitrary Functors, and use Const
to derive a field accessor (and the equally trivial Identity
to derive a field updater).
Traversable
types, as pigworker mentions, are another example of this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With