
Brock Peabody wrote:
Please excuse my newbiness, but in this snippet:
data (Monad m) => DataType m = DataType { f :: Char -> m () }
test_function :: (Monad m) => DataType m -> m () ^^^^^^^^^^^^ test_function d = f d 'C'
Why is "(Monad m) =>" required, when the definition of DataType already implies it? Is there an easier way to do this or will I have to have it in all signatures containing DataType?
This is exactly the same question I had when I started learning Haskell. The reason is that you are explicitly giving a type annotation for test_function, and whenever you give a type annotation what you see is what you get: the compiler doesn't add any extra things to it. If you had not given any type signature the inferred type would have been Monad m => DataType m -> m () as expected, whereas when you wrote test_function :: DataType m -> m () you are actively telling the compiler there is no context at all, but the compiler needs the context in this particular function in order to apply f. The context is not needed in all functions which use DataType - only in those functions which actually make use of m's Monad'ness, so you could write: test2 :: DataType m -> DataType m test2 x = x (See http://haskell.org/onlinereport/decls.html#user-defined-datatypes section 4.2.1 for more info) There was a post a while back (unfortunately I can't seem to locate it) where someone posted a link to some guidelines on haskell coding style where one guideline was never to use contexts in data declarations. Regards, Brian. -- Logic empowers us and Love gives us purpose. Yet still phantoms restless for eras long past, congealed in the present in unthought forms, strive mightily unseen to destroy us. http://www.metamilk.com