
On 2016-06-04 19:56, Daniel Bergey wrote:
I think "a functor is a container" is not so helpful. It works OK for Maybe and List, but it doesn't seem helpful in understanding Either, Reader, Writer, State, Continuation, promises. This is correct. However, a large class of types form what are called "Representable Functors". These include Lists, Trees, ((->) r), etc.
toFunction xs = \i -> xs !! i toList f = fromList $ map f [0..] I *think* it's the case that for (r ->), there isn't anything we can do with the Monad instance that we can't do with Applicative. If someone can confirm or refute that, I'd appreciate it. That's of course not true in general for other monads. Indeed, for any representable functor, this all follows from the fact
A representable functor is any type f with an isomorphism `(f a ~ r -> a)` for some r. For example, `Stream a ~ Natural -> a` under the isomorphism: that we can write a lawful join from Reader's <*>. Letting `join m = flip ($) <*> m`, we have:
(join . pure) x = \r -> ($ r) (const x r) = \r -> x $ r = x (join . fmap pure) x = \r -> ($ r) ((pure . x) r) = \r -> (const (x r)) r = \r -> x r = x (join . fmap join) x = \r -> ($ r) ((join . x) r) = \r -> join (x r) r = \r -> (\s -> ($s) (x r s)) r = \r -> x r r r = \r -> ($r) (\s -> x s s) r = join (\s -> ($s) (x s)) = (join . join) x
Hence, given the applicative instance for Reader, we obtain the Monad instance for free. Therefore, working under the isomorphism, we have the same for any representable functor. In particular, this gives that Stream is a Monad, where return gives the constant stream and join takes the diagonal of a stream of streams. Again, as noted, this is more or less the only way in which the "Functors/Applicatives/Monads are nice/nicer/nicest containers" analogy works. There are more things in heaven and earth than are described in that analogy, but it's a start. Hope this helps, and that it lacks errors/misleading material, Gesh P.S. Code for working with representable functors can be found in representable-functors. Code for working with Streams can be found in streams. Both are on Hackage.