
(Inspired by this[1] reddit thread.) When combining monadic and non-monadic code, I've often wished for a magical combinator of type (Monad m) => ((a -> b) -> c) -> (a -> m b) -> m c which would let me inject a monadic function into a pure one, then wrap the ultimate result to ensure that no nastiness escapes. Now, I'm pretty sure that writing such a combinator as-is is impossible. My question is, what restrictions/changes would be necessary for a similar combinator to be definable and well-behaved? (Obviously it would be impossible to ensure that the (m b)s get chained in any particular order, for order-sensitive monads, but it would be the caller's responsibility to ensure order-irrelevance in this case.) As a thought experiment, I imagined an implementation for IO using unsafePerformIO. This makes it easy to give the injected function the right type, and it's possible to use return to give the result the correct type too. Unfortunately, the semantics fail: if the injected function is used lazily, there's no way to ensure that the unsafe IO actions actually take place before the rest of the IO-based program, and it's possible for them to show up later than expected. I suspect that even in a strict language, lambda-abstractions would cause similar trouble. [1] http://programming.reddit.com/info/2n6eh/comments Stuart Cook