On Sat, Dec 5, 2009 at 10:33 PM, José Iborra <pepeiborra at 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/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20091205/4682b2d8/attachment.html