[Haskell-beginners] Functions as containers; implications on being a Monad ((->) r)
Gesh
gesh at gesh.uni.cx
Sun Jun 5 00:10:47 UTC 2016
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.
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:
> 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
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.
More information about the Beginners
mailing list