Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are applicative functors composed with the applicative style really independent?

I've come to understand functors, applicative functors, and monads as follows:

  • Functors: computations that can be mapped over.
  • Applicative functors: independent computations whose results can be combined together.
  • Monad: (possibly, but not necessarily) dependent computations that can be chained.

However, there is something about Applicative that conflicts with my understanding... Here is a Haskell example of a parser defined on the basis of more basic parsers using the applicative style:

(,) <$> parseName <*> parseEmail

The effects of the two parsers, parseName and parseEmail, are not independent, because they both consume tokens from the same input stream, e.g.

Jubobs [email protected]

parseEmail can only consume what hasn't been consumed by parseName. How, then, can the two computations be said to be independent?

like image 633
jub0bs Avatar asked Nov 27 '16 19:11

jub0bs


People also ask

Could you comfortably explain the difference between a monad and an applicative functor?

Functors apply a function to a wrapped value: Applicatives apply a wrapped function to a wrapped value: Monads apply a function that returns a wrapped value to a wrapped value. Monads have a function >>= (pronounced "bind") to do this.

Is applicative a functor?

Applicative functors are the programming equivalent of lax monoidal functors with tensorial strength in category theory. Applicative functors were introduced in 2008 by Conor McBride and Ross Paterson in their paper Applicative programming with effects.

Are all monads applicative?

Monads are not a replacement for applicative functors Instead, every monad is an applicative functor (as well as a functor). It is considered good practice not to use >>= if all you need is <*>, or even fmap.

How are functions functors?

In functional programming, a functor is a design pattern inspired by the definition from category theory, that allows for a generic type to apply a function inside without changing the structure of the generic type. Simple examples of this are Option and collection types.


1 Answers

The independence here is not saying that one computation cannot detect what other computations have been run - that is, it's not supposed to be the case that parseName has no effect on parseEmail. Rather, you cannot make use of the applicative value (the name parsed by parseName) to choose what applicative computation to run next: you can only ever parse a generic email, rather than, say, parsing an email address while checking that it does not contain the parsed name.

Another way of putting it is that if you use only applicative functions, the overall "shape" of your computation is predetermined ahead of time: you will always parse a name, followed by an email address. If you used monadic functions, you could make decisions about what to parse next based on the results of previous parses, letting you change the shape of your computation as it is running.

like image 136
amalloy Avatar answered Dec 01 '22 07:12

amalloy