On Sat, Dec 5, 2009 at 10:33 PM, José Iborra <pepeibo...@gmail.com> wrote:
> > On Dec 5, 2009, at 6:58 PM, Michael Snoyman wrote: > > > Hi all, > > > > Well, I've got two problems which both want to be solved with undecidable > and overlapping instances. Obviously, I'd like to try and avoid them. For > the record, the problems have to do with the control-monad-failure and > convertible packages. The code below *should* make clear what I'm trying to > accomplish: > > > > -- failure should not be limited to just monads, so... > > class Failure e f where > > failure :: e -> f v > > class (Functor f, Failure e f) => FunctorFailure e f > > instance (Functor f, Failure e f) => FunctorFailure e f -- undecidable, > overlaps > > class (Applicative f, Failure e f) => ApplicativeFailure e f > > instance (Applicative f, Failure e f) => ApplicativeFailure e f -- > undecidable, overlaps > > class (Monad f, Failure e f) => MonadFailure e f > > instance (Monad f, Failure e f) => MonadFailure e f -- undecidable, > overlaps > > > > (Functor|Monad|Applicative)Failure are little more than class synonyms, > right ? > Or equivalently, do you envision the need of writing, say, a MonadFailure > instance for a type A which which works differently than the existing > Failure instance for A? > If the answer is no as I presume, then you don't want overlapping > instances. > > Regarding undecidable instances, I will say that from my point of view they > do not constitute a language extension. > MPTCs are the language extension here. Since MPTCs can lead to > non-terminating type checking, > a compiler can either allow any use of them, employ a termination prover to > ensure that only well-behaved instances are defined, > or impose a set of restrictions that ensure termination. GHC does the > latter, rather conservatively in some cases, and undecidable > instances is just a compiler flag that puts the burden of termination > checking on the user. > > In this case it is obvious that non-termination is not going to be a > problem for the instances defined above. > Since you have already decided MPTCs are ok, in my opinion undecidable > instances are fine here. > But I realize this is not the usual stance, so I might be wrong. > > Sounds reasonable to me. I'm waiting for the boogey man to jump out though and explain why undecidables here will get me gored to death by a raptor [1]. > > > And now the convertible issue. I want two type classes: Convert for > anything which *might* be convertible, but might not. For example, sometimes > a String can be converted to an Int (like the string "5"), but sometimes it > will fail (like "five"). TotalConvert is when something *is* convertible, > such as Int to String (simply the show function). Thus the following: > > > > class Convert x y where > > convert :: x -> Maybe y > > class Convert x y => TotalConvert x y where > > totalConvert :: x -> y > > instance TotalConvert x y => Convert x y where -- Boom! > > convert = Just . totalConvert > > > In this case Convert is not just a class synonym, so you are going to run > into trouble with that code. > > I would do this as follows: > > class Convert x y => TotalConvert x y where > totalConvert :: x -> y > totalConvert = fromJust . convert > > For instance, > > instance Convert Integer Double where convert = Just . fromIntegral > instance TotalConvert Double -- that's all > > Interestng approach. The current approach is *almost* the same, just leaves off the default definition. I'd be wary of putting in a definition like that; although it saves a line of typing, it let's a partial function get in which could cause trouble for unsuspecting users. But it is a possibility. > > Cheers, > pepe [1] http://xkcd.com/292/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe