Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a Functor / Applicative be tied to one specific type or structure?

I’m trying to understand the applicative typeclass, and in particular the <*> function. Now I see its type signature is f (a -> b) -> f a -> f b and I take it that f is a functor, which I think of as some kind of structure wrapping some data. It appears to me that f must handle generic types, specifically it must be possible for f to have the parameterized types a, b, and in fact it must also support a -> b.

If my understanding is correct, then what we are doing is working with a typeclass f that is initially intended to wrap some data, like say a list of strings or a tree containing file buffers or whatever random thing we might want. But f must not be committed to any one type, because not only must it handle such a type but it is also required to handle functions from the data to the other data. Thus if we had an example implementation of <*> which contained

Just2 f <*> j = fmap f j

the way to read this is that j is some kind of data inside of a Just2. f is a function which maps data to data. And f is wrapped in a Just2.

Is all of that right? Fundamentally my question is: Must anything applicative be so generic that it can always simultaneously handle arbitrary data and also functions from data to data? Or is there some way that you could have an applicative such that the only data it allows inside is, say, lists?

like image 868
Addem Avatar asked May 18 '20 20:05

Addem


People also ask

Is applicative a functor?

Like monads, applicative functors are functors with extra laws and operations; in fact, Applicative is an intermediate class between Functor and Monad .

What are functor laws?

Functor Laws If two sequential mapping operations are performed one after the other using two functions, the result should be the same as a single mapping operation with one function that is equivalent to applying the first function to the result of the second.

Is functor a type class?

Functor in Haskell is a typeclass that provides two methods – fmap and (<$) – for structure-preserving transformations. To implement a Functor instance for a data type, you need to provide a type-specific implementation of fmap – the function we already covered.

Are all monads applicative functors?

Every Monad is an Applicative Just as IO , every monad can be made into an applicative functor.


1 Answers

Yes, your understanding is largely correct. In particular, any specific Applicative, say one named Foo, has an associated specialization of the function pure with type signature:

pure :: a -> Foo a

that must work for any type a selected by the caller, such as:

> pure 10 :: Foo Int
> pure length :: Foo (String -> Int)

So, whatever Foo is, it has to be able to "handle" any provided type without limitations because pure can technically be applied to any type without limitations.

One cautionary note, though. The idea that a functor f "wraps" data, so that f Int is somehow a "container" of Int values, can be a helpful intuition and is often literally correct (e.g., lists, trees, etc.), but it's not always strictly true. (Some counterexamples include the functors IO, (->) r, and Const b, which "contain" values in a very different sense than real containers.)

like image 184
K. A. Buhr Avatar answered Oct 27 '22 09:10

K. A. Buhr