In Haskell, there are many data types that would form monads were it not for the presence of type-class constraints on the operations on that data type. This is a frustrating problem in practice, because there is a considerable amount of support and infrastructure for monads that these data types cannot use. Using several examples, we show that a monadic computation can be restructured into a normal form such that the standard monad class can be used. The technique is not specific to monads, and we show how it can also be applied to other structures, such as applicative functors. One significant use case for this technique is domain-specific languages, where it is often desirable to compile a deep embedding of a computation to some other language, which requires restricting the types that can appear in that computation.
Categories and Subject Descriptors
MotivationThe use of monads to structure computation was first suggested by Moggi [27,28] and Spivey [36], and was then enthusiastically taken up by Wadler [41,42]. Monads have since proved to be a popular and frequently occurring structure, and are now one of the most prevalent abstractions within the Haskell language.However, there are many data structures that are monad-like, but cannot be made instances of the Monad type class (Figure 1) because of type-class constraints on their operations. The classic example of this is the Set data type, which imposes an ordering constraint on its operations. This is unfortunate, because the Haskell language and libraries provide a significant amount of infrastructure to support arbitrary monads, including special syntax. We will refer to this situation where type-class constraints prevent a Monad instance from being declared as the "constrained-monad problem". This paper is about investigating solutions to this problem, with an emphasis on the particular solution of normalizing a deep embedding of a monadic computation. We aim to understand the utility of This is the author's version of the work. It is posted here by permission of ACM for your personal use. Not for redistribution. The definitive version was published in ICFP '13, September 25-27, 2013, Boston, MA, USA, http://dx.doi.org/10.1145 class Monad (m :: * → * ) where the various solutions, publicize their usefulness, and explain how they relate to each other.We begin by giving three concrete examples of the constrainedmonad problem: three data types that would be monads were it not for the presence of class constraints on their operations.