On Mon, 21 Mar 2005 20:29:35 -0500 (Eastern Standard Time), S. Alexander Jacobson <[EMAIL PROTECTED]> wrote: > I just discovered implicit parameters. To everyone involved with > making them, THANK YOU. They are blazingly useful/powerful for server > handler style libraries where you want to make a veriety of local > environment information available to the handlers without burdening > the handlers with a big dictionary object to carry around. FANTASTIC. I like to think of implicit parameters as a direct-style reader monad. Therefore, they can be used interchangably with reader monads (or with explicit passing of the parameter, for that matter). Which one you choose is of course a matter of taste, but personally, I prefer the monadic approach, since it is easier to extend (maybe you later discover that you really needed state) and it is the usual (and portable) Haskell solution. Furthermore, because `(->) r' already is a reader monad, the code can often be kept very consice.
The situation is different if you've already written some code and realize you need an additional parameter in a couple of functions. Monadifying all that code (or explicitely threading the parameter) is usually a lot of trouble and the change might be only experimental anyway, so with implicit parameters, you can just change a few signatures and be done. > That being said, they so powerful they are proabably easy to abuse. > Could those experienced with this feature provide warnings about > possible problems with overuse? I've only used them sparsely and I think that's the way to go. Also, you should be aware of a few common problems: 1. Recursive functions http://www.haskell.org/pipermail/haskell-cafe/2005-January/008571.html This is not surprising if you consider how type inference for recursive functions works, but it is obviously the wrong thing to do. Personally, I'd be happy if (mutually) recursive functions using implicit parameters without a type signature were rejected, because to do it correctly, some sort of polymorphic recursion is necessary. 2. The monomorphism restriction Consider > a :: Int > a = let ?foo = 0 in b where > b :: (?foo :: Int) => Int > b = let ?foo = 1 in c where > c = ?foo The meaning of this code depends on the flag -f(no)-monomorphism-restriction since with the monomorphism turned on, `c' gets the monomorphic type `Int', and the `?foo' in the definition of `c' refers to the implicit parameter of `b', so `a' evaluates to `0'. On the other hand, without the monomorphism restriction, the type of `c' becomes `(?foo :: Int) => Int', and it is easy to see that `a' evaluates to `0'. The fact that the meaning depends on the type signature actually isn't that bad; after all, in explicit monadic code, you would have to make the same choice. The interaction with the monomorphism restriction, however, seems very unfortunate. Btw, to explicitely type a declaration in a let binding, the style "let x :: a = b" isn't enough, it needs to be "let x :: a; x = b". Thomas _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe