
Recently I discovered for myself "monadLib" as an alternative for mtl-like packages. It seems that "monadLib" has better interface, but I'm quite confused with it's type classes: they have the monad type variable before the effect type variable (e.g. "ReaderM m i" instead of "ReaderM i m"). AFAIU, this ordering makes impossible to use these type classes in conjunction with GHC's cunning newtype deriving extension. Of course one can easily derive all instances using functionality provided by "MonadLib.Derive" module, but this is a boilerplate. Is there any way to avoid this boilerplate? -- Emil.

Emil Melnikov
Recently I discovered for myself "monadLib" as an alternative for mtl-like packages. It seems that "monadLib" has better interface, but I'm quite confused with it's type classes: they have the monad type variable before the effect type variable (e.g. "ReaderM m i" instead of "ReaderM i m"). AFAIU, this ordering makes impossible to use these type classes in conjunction with GHC's cunning newtype deriving extension. Of course one can easily derive all instances using functionality provided by "MonadLib.Derive" module, but this is a boilerplate. Is there any way to avoid this boilerplate?
When discussing a similar issue with Manuel Chakravarty, he convinced me that cunning newtype deriving is actually rather bad in practice and shouldn't be used as there's a lack of proofs or some such (I can't remember the arguments, but I remember being convinced by them :p). -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On 07/18/2010 08:27 AM, Ivan Lazar Miljenovic wrote:
When discussing a similar issue with Manuel Chakravarty, he convinced me that cunning newtype deriving is actually rather bad in practice and shouldn't be used as there's a lack of proofs or some such (I can't remember the arguments, but I remember being convinced by them :p).
Did these arguments apply to all newtype deriving or only to some subset of it? I don't know if "cunning" newtype deriving is a special kind of newtype deriving (multiparameter?) or if it's just being thrown around. - Jake

Jake McArthur
On 07/18/2010 08:27 AM, Ivan Lazar Miljenovic wrote:
When discussing a similar issue with Manuel Chakravarty, he convinced me that cunning newtype deriving is actually rather bad in practice and shouldn't be used as there's a lack of proofs or some such (I can't remember the arguments, but I remember being convinced by them :p).
Did these arguments apply to all newtype deriving or only to some subset of it? I don't know if "cunning" newtype deriving is a special kind of newtype deriving (multiparameter?) or if it's just being thrown around.
All; it was something to do with there being no guaranteed safety with newtype deriving. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On 2010, July 18, 23:27
Ivan Lazar Miljenovic
When discussing a similar issue with Manuel Chakravarty, he convinced me that cunning newtype deriving is actually rather bad in practice and shouldn't be used as there's a lack of proofs or some such (I can't remember the arguments, but I remember being convinced by them :p).
Hmm... I can't imagine how it is possible, since new and original types are isomorphic. Can you give me some pointers to this discussion (links or keywords)? -- Emil.

Hi,
When using monadLib, I use newtype deriving to get the Functor,
Applicative, and Monad instances for my custom newtyped monad. Those
work just fine, and there is nothing unsafe about them.
For a custom monad, I usually don't derive MonadLib's effect classes
directly. Instead, I tend to define new operations specific to the
monad. This has the benefit of abstracting away internal
implementation details, which makes it easier to change or extend the
monad later. For example, to implement a monad which provides a
source of unique identifiers, I might use a state transformer:
newtype MyMonad a = MyMonad (StateT Int ...)
Now, instead of deriving a "StateM" instance, I would define a custom
operation for obtaining new names, something like this:
newName :: MyMonad Name
newName = MyMonad (do x <- get; set (x + 1); return (mkName x))
This is why GHC's limitation of deriving only the last argument of a
class has not been too much of a problem for me. On a more general
note, I don't think that there is anything particularly difficult
about lifting the "deriving only the last argument" restriction,
except for picking a reasonable notation and finding a willing
contributor to hack it up. (Generalized generalized deriving anyone
:-) ?) If you are interested in some of the issues with generalized
newtype deriving in general, this thread has some examples:
http://osdir.com/ml/haskell-cafe@haskell.org/2010-03/msg00388.html
Hope that this helps,
-Iavor
On Sun, Jul 18, 2010 at 9:59 AM, Emil Melnikov
On 2010, July 18, 23:27 Ivan Lazar Miljenovic
wrote: When discussing a similar issue with Manuel Chakravarty, he convinced me that cunning newtype deriving is actually rather bad in practice and shouldn't be used as there's a lack of proofs or some such (I can't remember the arguments, but I remember being convinced by them :p).
Hmm... I can't imagine how it is possible, since new and original types are isomorphic.
Can you give me some pointers to this discussion (links or keywords)?
-- Emil. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 2010, July 18, 11:10
Iavor Diatchki
Hi, When using monadLib, I use newtype deriving to get the Functor, Applicative, and Monad instances for my custom newtyped monad. Those work just fine, and there is nothing unsafe about them.
For a custom monad, I usually don't derive MonadLib's effect classes directly. Instead, I tend to define new operations specific to the monad. This has the benefit of abstracting away internal implementation details, which makes it easier to change or extend the monad later. For example, to implement a monad which provides a source of unique identifiers, I might use a state transformer:
newtype MyMonad a = MyMonad (StateT Int ...)
Now, instead of deriving a "StateM" instance, I would define a custom operation for obtaining new names, something like this:
newName :: MyMonad Name newName = MyMonad (do x <- get; set (x + 1); return (mkName x))
Hello, and thanks for such quick answer. Your rationale showed me that deriving all possible instances is a wrong way, because it breaks abstraction. Somehow I didn't saw it. Moreover, now I suppose that "don't derive unnecessary instances" statement should be highlighted in Haskell wiki page about type classes/monads. -- Emil.

On Sun, Jul 18, 2010 at 5:59 PM, Emil Melnikov
On 2010, July 18, 23:27 Ivan Lazar Miljenovic
wrote: When discussing a similar issue with Manuel Chakravarty, he convinced me that cunning newtype deriving is actually rather bad in practice and shouldn't be used as there's a lack of proofs or some such (I can't remember the arguments, but I remember being convinced by them :p).
Hmm... I can't imagine how it is possible, since new and original types are isomorphic.
Can you give me some pointers to this discussion (links or keywords)?
They are isomorphic, but distinct. This trac ticket is relevant: http://hackage.haskell.org/trac/ghc/ticket/1496

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 7/18/10 09:27 , Ivan Lazar Miljenovic wrote:
When discussing a similar issue with Manuel Chakravarty, he convinced me that cunning newtype deriving is actually rather bad in practice and shouldn't be used as there's a lack of proofs or some such (I can't remember the arguments, but I remember being convinced by them :p).
It's worse than lack of proofs; it demonstrably produces bad code in a number of situations. - -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkxDUEwACgkQIn7hlCsL25VgywCgo4TO5T9PY2FnOjThbVzWcpsY LUEAoLPfLuZTnmvkjadVKWX9ddUwwjaJ =03Zb -----END PGP SIGNATURE-----
participants (6)
-
Ben Millwood
-
Brandon S Allbery KF8NH
-
Emil Melnikov
-
Iavor Diatchki
-
Ivan Lazar Miljenovic
-
Jake McArthur