This imaginary more-restricted monad would have only one method `pop`, which would liberate you from doing (in `str` and then duplicated in `many`): `get >>= \case { s:ss -> put ss >> {- process s -}` replacing it with `pop >>= \s -> {- process s -}`. (Could be `\(Just s) -> {- process s -}` to account for the fact that the stack might be empty already.)

Actually, I was able to Google a very similar thing:

http://hackage.haskell.org/package/hexpr-0.0.0.0/docs/Control-Monad-Stack.html

There are several issues there, though: it’s basically dead, it’s pop and push simultaneously, it hardcodes list as the implementation of this behavior while many other container-like structures might do as well or better.

Also, minor: I prefer `liftA2 (:) s (many s)` over `(:) s many s` because I find the latter too noisy.

]]>Speaking of Selective, we need to implement this function (excuse the name clash):

select :: Enumeration (Either a b) -> Enumeration (a -> b) -> Enumeration b

select x y = …

Let’s look at just computing the Cardinality of the result. The answer is:

#x.Left * #y + #x.Right

where #x.Left and #x.Right are the numbers of occurrences of Left and Right values in the first enumeration x, and #y is the cardinality of the second enumeration y. Why? Because whenever we get a value of type Left a, we need to apply one possible function to it. But we have no way of extracting #x.Left and #x.Right from x in the current representation of the Enumeration data type. And I’m not sure how this could be fixed.

Note: I’m being a bit imprecise here, because every Applicative instance can be given a lawful Selective instance simply by using the function selectA, which performs both effects regardless of whether the value is Left or Right. This would essentially duplicate values of type Right b #y times, essentially behaving in an Applicative way. But I think such an implementation would not be very useful; we really want to avoid duplicating values in the result in order to have a useful Selective instance.

]]>