Even more generalized newtype deriving - haskell

Newtypes are often used to change the behavior of certain types when used in certain class contexts. For example, one would use the Data.Monoid.All wrapper to change the behavior of Bool when used as a Monoid.
I'm currently writing such a newtype wrapper that would apply to a large range of different types. The wrapper is supposed to change the behavior of one specific class instance. It might look like this:
newtype Wrapper a = Wrapper a
instance Special a => Special (Wrapper a) where
-- ...
However, adding this wrapper will often change the usability of the wrapped type. For example, if I previously was able to use the function mconcat :: Monoid a => [a] -> a, I am not able to now use it for a list of wrapped values.
I can of course use -XGeneralizedNewtypeDeriving and newtype Wrapper a = Wrapper a deriving (Monoid). However, this only solves the problem for Monoid and no other class, while I will be dealing with an open world full of different classes, and standalone orphan generalized newtype deriving is not really a practical option. Ideally, I'd like to write deriving hiding (Special) (deriving every class except Special), but that's not valid Haskell, of course.
Is there some way of doing this or am I just screwed and need to add a GHC feature request?

Look, GeneralizedNewtypeDeriving is unsafe. In that vein, here is an unsafe way of doing it
{-# LANGUAGE GADTs, ConstraintKinds #-}
import Data.Monoid
import Unsafe.Coerce
data Dict c where
Dict :: c => Dict c
newtype Wrapper a = Wrapper a
addDictWrapper :: Dict (f a) -> Dict (f (Wrapper a))
addDictWrapper = unsafeCoerce
you can then use it anytime you need the typeclass instance
intWrapperNum :: Dict (Num (Wrapper Int))
intWrapperNum = addDictWrapper Dict
two :: Wrapper Int
two = case intWrapperNum of
Dict -> 1 + 1
this system of passing around explicit dictionaries is highly general, and has a pretty good (although experimental) library to support it called Data.Constraint

I'm afraid there is no direct way how to do that in GHC. But I think you could solve your problem using Template Haskell.

Related

How to declare instances of a typeclass (like Show) for all types in my own typeclass?

I have a typeclass:
class Wrapper w where
open :: w -> Map String Int
close :: Map String Int -> w
It doesn't look very useful, but I use it to strongly (not just a type synonym) distinguish between semantically different varieties of Map String Ints:
newtype FlapMap = Flap (Map String Int)
newtype SnapMap = Snap (Map String Int)
...
and still have functions that operate on any type of the class.
Is there a better way to do this distinction (maybe without the Wrapper instances boilerplate)?
I want to do this:
instance (Wrapper wrapper) => Show wrapper where
show w = show $ toList $ open w
instead of writing many boilerplate Show instances as well.
Via FlexibleInstances and UndecidableInstances, GHC leads me to a point where it thinks my instance declaration applies to everything, as it allegedly clashes with the other Show instances in my code and in GHC.Show. HaskellWiki and StackOverflow answerers and HaskellWiki convince me OverlappingInstances is not quite safe and possibly confusing. GHC doesn't even suggest it.
Why does GHC first complain about not knowing which instance of fx Show Int to pick (so why it doesn't look at the constraint I give at compile time?) and then, being told that instances may overlap, suddenly know what to do?
Can I avoid allowing OverlappingInstances with my newtypes?
You can’t do this without OverlappingInstances, which as you mention, is unpredictable. It won’t help you here, anyway, so you pretty much can’t do this at all without a wrapper type.
That’s rather unsatisfying, of course, so why is this the case? As you’ve already determined, GHC does not look at the instance context when picking an instance, only the instance head. Why? Well, consider the following code:
class Foo a where
fooToString :: a -> String
class Bar a where
barToString :: a -> String
data Something = Something
instance Foo Something where
fooToString _ = "foo something"
instance Bar Something where
barToString _ = "bar something"
instance Foo a => Show a where
show = fooToString
instance Bar a => Show a where
show = barToString
If you consider the Foo or Bar typeclasses in isolation, the above definitions make sense. Anything that implements the Foo typeclass should get a Show instance “for free”. Unfortunately, the same is true of the Bar instance, so now you have two valid instances for show Something.
Since typeclasses are always open (and indeed, Show must be open if you are able to define your own instances for it), it’s impossible to know that someone will not come along and add their own similar instance, then create an instance on your datatype, creating ambiguity. This is effectively the classic diamond problem from OO multiple inheritance in typeclass form.
The best you can get is to create a wrapper type that provides the relevant instances:
{-# LANGUAGE ExistentialQuantification #-}
data ShowableWrapper = forall w. Wrapper w => ShowableWrapper w
instance Show ShowableWrapper where
show (ShowableWrapper w) = show . toList $ open w
At that point, though, you really aren’t getting much of an advantage over just writing your own showWrapper :: Wrapper w => w -> String function.

How can I make my type an instance of Arbitrary?

I have the following data and function
data Foo = A | B deriving (Show)
foolist :: Maybe Foo -> [Foo]
foolist Nothing = [A]
foolist (Just x) = [x]
prop_foolist x = (length (foolist x)) == 1
when running quickCheck prop_foolist, ghc tells me that Foo needs to be an instance of Arbitrary.
No instance for (Arbitrary Foo) arising from a use of ‘quickCheck’
In the expression: quickCheck prop_foolist
In an equation for ‘it’: it = quickCheck prop_foolist
I tried data Foo = A | B deriving (Show, Arbitrary), but this results in
Can't make a derived instance of ‘Arbitrary Foo’:
‘Arbitrary’ is not a derivable class
Try enabling DeriveAnyClass
In the data declaration for ‘Foo’
However, I can't figure out how to enble DeriveAnyClass. I just wanted to use quickcheck with my simple function! The possible values of x is Nothing, Just A and Just B. Surely this should be possible to test?
There are two reasonable approaches:
Reuse an existing instance
If there's another instance that looks similar, you can use it. The Gen type is an instance of Functor, Applicative, and even Monad, so you can easily build generators from other ones. This is probably the most important general technique for writing Arbitrary instances. Most complex instances will be built up from one or more simpler ones.
boolToFoo :: Bool -> Foo
boolToFoo False = A
boolToFoo True = B
instance Arbitrary Foo where
arbitrary = boolToFoo <$> arbitrary
In this case, Foo can't be "shrunk" to subparts in any meaningful way, so the default trivial implementation of shrink will work fine. If it were a more interesting type, you could have used some analogue of
shrink = map boolToFoo . shrink . fooToBool
Use the pieces available in Test.QuickCheck.Arbitrary and/or Test.QuickCheck.Gen
In this case, it's pretty easy to just put together the pieces:
import Test.QuickCheck.Arbitrary
data Foo = A | B
deriving (Show,Enum,Bounded)
instance Arbitrary Foo where
arbitrary = arbitraryBoundedEnum
As mentioned, the default shrink implementation would be fine in this case. In the case of a recursive type, you'd likely want to add
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics (Generic)
and then derive Generic for your type and use
instance Arbitrary ... where
...
shrink = genericShrink
As the documentation warns, genericShrink does not respect any internal validity conditions you may wish to impose, so some care may be required in some cases.
You asked about DeriveAnyClass. If you wanted that, you'd add
{-# LANGUAGE DeriveAnyClass #-}
to the top of your file. But you don't want that. You certainly don't want it here, anyway. It only works for classes that have a full complement of defaults based on Generics, typically using the DefaultSignatures extension. In this case, there is no default arbitrary :: Generic a => Gen a line in the Arbitrary class definition, and arbitrary is mandatory. So an instance of Arbitrary produced by DeriveAnyClass will produce a runtime error as soon as QuickCheck tries to call its arbitrary method.

Which dictionary does GHC choose when more than one is in scope?

Consider the following example:
import Data.Constraint
class Bar a where
bar :: a -> a
foo :: (Bar a) => Dict (Bar a) -> a -> a
foo Dict = bar
GHC has two choices for the dictionary to use when selecting a Bar instance in foo: it could use the dictionary from the Bar a constraint on foo, or it could use the runtime Dict to get a dictionary. See this question for an example where the dictionaries correspond to different instances.
Which dictionary does GHC use, and why is it the "correct" choice?
It just picks one. This isn't the correct choice; it's a pretty well-known wart. You can cause crashes this way, so it's a pretty bad state of affairs. Here is a short example using nothing but GADTs that demonstrates that it is possible to have two different instances in scope at once:
-- file Class.hs
{-# LANGUAGE GADTs #-}
module Class where
data Dict a where
Dict :: C a => Dict a
class C a where
test :: a -> Bool
-- file A.hs
module A where
import Class
instance C Int where
test _ = True
v :: Dict Int
v = Dict
-- file B.hs
module B where
import Class
instance C Int where
test _ = False
f :: Dict Int -> Bool
f Dict = test (0 :: Int)
-- file Main.hs
import TestA
import TestB
main = print (f v)
You will find that Main.hs compiles just fine, and even runs. It prints True on my machine with GHC 7.10.1, but that's not a stable outcome. Turning this into a crash is left to the reader.
GHC just picks one, and this is the correct choice. Any two dictionaries for the same constraint are supposed to be equal.
OverlappingInstances and IncoherentInstances are basically equivalent in destructive power; they both lose instance coherence by design (any two equal constraints in your program being satisfied by the same dictionary). OverlappingInstances gives you a little more ability to work out which instances will be used on a case-by-case basis, but this isn't that useful when you get to the point of passing around Dicts as first class values and so on. I would only consider using OverlappingInstances when I consider the overlapping instances extensionally equivalent (e.g., a more efficient but otherwise equal implementation for a specific type like Int), but even then, if I care enough about performance to write that specialized implementation, isn't it a performance bug if it doesn't get used when it could be?
In short, if you use OverlappingInstances, you give up the right to ask the question of which dictionary will be selected here.
Now it's true that you can break instance coherence without OverlappingInstances. In fact you can do it without orphans and without any extensions other than FlexibleInstances (arguably the problem is that the definition of "orphan" is wrong when FlexibleInstances is enabled). This is a very long-standing GHC bug, which hasn't been fixed in part because (a) it actually can't cause crashes directly as far as anybody seems to know, and (b) there might be a lot of programs that actually rely on having multiple instances for the same constraint in separate parts of the program, and that might be hard to avoid.
Getting back to the main topic, in principle it's important that GHC can select any dictionary that it has available to satisfy a constraint, because even though they are supposed to be equal, GHC might have more static information about some of them than others. Your example is a little bit too simple to be illustrative but imagine that you passed an argument to bar; in general GHC doesn't know anything about the dictionary passed in via Dict so it has to treat this as a call to an unknown function, but you called foo at a specific type T for which there was a Bar T instance in scope, then GHC would know that the bar from the Bar a constraint dictionary was T's bar and could generate a call to a known function, and potentially inline T's bar and do more optimizations as a result.
In practice, GHC is currently not this smart and it just uses the innermost dictionary available. It would probably be already better to always use the outermost dictionary. But cases like this where there are multiple dictionaries available are not very common, so we don't have good benchmarks to test on.
Here's a test:
{-# LANGUAGE FlexibleInstances, OverlappingInstances, IncoherentInstances #-}
import Data.Constraint
class C a where foo :: a -> String
instance C [a] where foo _ = "[a]"
instance C [()] where foo _ = "[()]"
aDict :: Dict (C [a])
aDict = Dict
bDict :: Dict (C [()])
bDict = Dict
bar1 :: String
bar1 = case (bDict, aDict :: Dict (C [()])) of
(Dict,Dict) -> foo [()] -- output: "[a]"
bar2 :: String
bar2 = case (aDict :: Dict (C [()]), bDict) of
(Dict,Dict) -> foo [()] -- output: "[()]"
GHC above happens to use the "last" dictionary which was brought into scope. I wouldn't rely on this, though.
If you limit yourself to overlapping instances, only, then you wouldn't be able to bring in scope two different dictionaries for the same type (as far as I can see), and everything should be fine since the choice of the dictionary becomes immaterial.
However, incoherent instances are another beast, since they allow you to commit to a generic instance and then use it at a type which has a more specific instance. This makes it very hard to understand which instance will be used.
In short, incoherent instances are evil.
Update: I ran some further tests. Using only overlapping instances and an orphan instance in a separate module you can still obtain two different dictionaries for the same type. So, we need even more caveats. :-(

Use of 'unsafeCoerce'

In Haskell, there is a function called unsafeCoerce, that turns anything into any other type of thing. What exactly is this used for? Like, why we would you want to transform things into each other in such an "unsafe" way?
Provide an example of a way that unsafeCoerce is actually used. A link to Hackage would help. Example code in someones question would not.
unsafeCoerce lets you convince the type system of whatever property you like. It's thus only "safe" exactly when you can be completely certain that the property you're declaring is true. So, for instance:
unsafeCoerce True :: Int
is a violation and can lead to wonky, bad runtime behavior.
unsafeCoerce (3 :: Int) :: Int
is (obviously) fine and will not lead to runtime misbehavior.
So what's a non-trivial use of unsafeCoerce? Let's say we've got an typeclass-bound existential type
module MyClass ( SomethingMyClass (..), intSomething ) where
class MyClass x where {}
instance MyClass Int where {}
data SomethingMyClass = forall a. MyClass a => SomethingMyClass a
Let's also say, as noted here, that the typeclass MyClass is not exported and thus nobody else can ever create instances of it. Indeed, Int is the only thing that instantiates it and the only thing that ever will.
Now when we pattern match to destruct a value of SomethingMyClass we'll be able to pull a "something" out from inside
foo :: SomethingMyClass -> ...
foo (SomethingMyClass a) =
-- here we have a value `a` with type `exists a . MyClass a => a`
--
-- this is totally useless since `MyClass` doesn't even have any
-- methods for us to use!
...
Now, at this point, as the comment suggests, the value we've pulled out has no type information—it's been "forgotten" by the existential context. It could be absolutely anything which instantiates MyClass.
Of course, in this very particular situation we know that the only thing implementing MyClass is Int. So our value a must actually have type Int. We could never convince the typechecker that this is true, but due to an outside proof we know that it is.
Therefore, we can (very carefully)
intSomething :: SomethingMyClass -> Int
intSomething (SomethingMyClass a) = unsafeCoerce a -- shudder!
Now, hopefully I've suggested that this is a terrible, dangerous idea, but it also may give a taste of what kind of information we can take advantage of in order to know things that the typechecker cannot.
In non-pathological situations, this is rare. Even rarer is a situation where using something we know and the typechecker doesn't isn't itself pathological. In the above example, we must be completely certain that nobody ever extends our MyClass module to instantiate more types to MyClass otherwise our use of unsafeCoerce becomes instantly unsafe.
> instance MyClass Bool where {}
> intSomething (SomethingMyClass True)
6917529027658597398
Looks like our compiler internals are leaking!
A more common example where this sort of behavior might be valuable is when using newtype wrappers. It's a fairly common idea that we might wrap a type in a newtype wrapper in order to specialize its instance definitions.
For example, Int does not have a Monoid definition because there are two natural monoids over Ints: sums and products. Instead, we use newtype wrappers to be more explicit.
newtype Sum a = Sum { getSum :: a }
instance Num a => Monoid (Sum a) where
mempty = Sum 0
mappend (Sum a) (Sum b) = Sum (a+b)
Now, normally the compiler is pretty smart and recognizes that it can eliminate all of those Sum constructors in order to produce more efficient code. Sadly, there are times when it cannot, especially in highly polymorphic situations.
If you (a) know that some type a is actually just a newtype-wrapped b and (b) know that the compiler is incapable of deducing this itself, then you might want to do
unsafeCoerce (x :: a) :: b
for a slight efficiency gain. This, for instance, occurs frequently in lens and is expressed in the Data.Profunctor.Unsafe module of profunctors, a dependency of lens.
But let me again suggest that you really need to know what's going on before using unsafeCoerce like this is anything but highly unsafe.
One final thing to compare is the "typesafe cast" available in Data.Typeable. This function looks a bit like unsafeCoerce, but with much more ceremony.
unsafeCoerce :: a -> b
cast :: (Typeable a, Typeable b) => a -> Maybe b
Which, you might think of as being implemented using unsafeCoerce and a function typeOf :: Typeable a => a -> TypeRep where TypeRep are unforgeable, runtime tokens which reflect the type of a value. Then we have
cast :: (Typeable a, Typeable b) => a -> Maybe b
cast a = if (typeOf a == typeOf b) then Just b else Nothing
where b = unsafeCoerce a
Thus, cast is able to ensure that the types of a and b really are the same at runtime, and it can decide to return Nothing if they are not. As an example:
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ExistentialQuantification #-}
data A = A deriving (Show, Typeable)
data B = B deriving (Show, Typeable)
data Forget = forall a . Typeable a => Forget a
getAnA :: Forget -> Maybe A
getAnA (Forget something) = cast something
which we can run as follows
> getAnA (Forget A)
Just A
> getAnA (Forget B)
Nothing
So if we compare this usage of cast with unsafeCoerce we see that it can achieve some of the same functionality. In particular, it allows us to rediscover information that may have been forgotten by ExistentialQuantification. However, cast manually checks the types at runtime to ensure that they are truly the same and thus cannot be used unsafely. To do this, it demands that both the source and target types allow for runtime reflection of their types via the Typeable class.
The only time I ever felt compelled to use unsafeCoerce was on finite natural numbers.
{-# LANGUAGE DataKinds, GADTs, TypeFamilies, StandaloneDeriving #-}
data Nat = Z | S Nat deriving (Eq, Show)
data Fin (n :: Nat) :: * where
FZ :: Fin (S n)
FS :: Fin n -> Fin (S n)
deriving instance Show (Fin n)
Fin n is a singly linked data structure that is statically ensured to be smaller than the n type level natural number by which it is parametrized.
-- OK, 1 < 2
validFin :: Fin (S (S Z))
validFin = FS FZ
-- type error, 2 < 2 is false
invalidFin :: Fin (S (S Z))
invalidFin = FS (FS FZ)
Fin can be used to safely index into various data structures. It's pretty standard in dependently typed languages, though not in Haskell.
Sometimes we want to convert a value of Fin n to Fin m where m is greater than n.
relaxFin :: Fin n -> Fin (S n)
relaxFin FZ = FZ
relaxFin (FS n) = FS (relaxFin n)
relaxFin is a no-op by definition, but traversing the value is still required for the types to check out. So we might just use unsafeCoerce instead of relaxFin. More pronounced gains in speed can result from coercing larger data structures that contain Fin-s (for example, you could have lambda terms with Fin-s as bound variables).
This is an admittedly exotic example, but I find it interesting in the sense that it's pretty safe: I can't really think of ways for external libraries or safe user code to mess this up. I might be wrong though and I'd be eager to hear about potential safety issues.
There is no use of unsafeCoerce I can really recommend, but I can see that in some cases such a thing might be useful.
The first use that springs to mind is the implementation of the Typeable-related routines. In particular cast :: (Typeable a, Typeable b) => a -> Maybe b achieves a type-safe behaviour, so it is safe to use, yet it has to play dirty tricks in its implementation.
Maybe unsafeCoerce can find some use when importing FFI subroutines to force types to match. After all, FFI already allows to import impure C functions as pure ones, so it is intrinsecally usafe. Note that "unsafe" does not mean impossible to use, but just "putting the burden of proof on the programmer".
Finally, pretend that sortBy did not exist. Consider then this example:
-- Like Int, but using the opposite ordering
newtype Rev = Rev { unRev :: Int }
instance Ord Rev where compare (Rev x) (Rev y) = compare y x
sortDescending :: [Int] -> [Int]
sortDescending = map unRev . sort . map Rev
The code above works, but feels silly IMHO. We perform two maps using functions such as Rev,unRev which we know to be no-ops at runtime. So we just scan the list twice for no reason, but that of convincing the compiler to use the right Ord instance.
The performance impact of these maps should be small since we also sort the list. Yet it is tempting to rewrite map Rev as unsafeCoerce :: [Int]->[Rev] and save some time.
Note that having a coercing function
castNewtype :: IsNewtype t1 t2 => f t2 -> f t1
where the constraint means that t1 is a newtype for t2 would help, but it would be quite dangerous. Consider
castNewtype :: Data.Set Int -> Data.Set Rev
The above would cause the data structure invariant to break, since we are changing the ordering underneath! Since Data.Set is implemented as a binary search tree, it would cause quite a large damage.

How do I write, "if typeclass a, then a is also an instance of b by this definition."

I have a typeclass MyClass, and there is a function in it which produces a String. I want to use this to imply an instance of Show, so that I can pass types implementing MyClass to show. So far I have,
class MyClass a where
someFunc :: a -> a
myShow :: a -> String
instance MyClass a => Show a where
show a = myShow a
which gives the error Constraint is no smaller than the instance head. I also tried,
class MyClass a where
someFunc :: a -> a
myShow :: a -> String
instance Show (MyClass a) where
show a = myShow a
which gives the error, ClassMyClass' used as a type`.
How can I correctly express this relationship in Haskell?
Thanks.
I should add that I wish to follow this up with specific instances of MyClass that emit specific strings based on their type. For example,
data Foo = Foo
data Bar = Bar
instance MyClass Foo where
myShow a = "foo"
instance MyClass Bar where
myShow a = "bar"
main = do
print Foo
print Bar
I wish to vigorously disagree with the broken solutions posed thus far.
instance MyClass a => Show a where
show a = myShow a
Due to the way that instance resolution works, this is a very dangerous instance to have running around!
Instance resolution proceeds by effectively pattern matching on the right hand side of each instance's =>, completely without regard to what is on the left of the =>.
When none of those instances overlap, this is a beautiful thing. However, what you are saying here is "Here is a rule you should use for EVERY Show instance. When asked for a show instance for any type, you'll need an instance of MyClass, so go get that, and here is the implementation." -- once the compiler has committed to the choice of using your instance, (just by virtue of the fact that 'a' unifies with everything) it has no chance to fall back and use any other instances!
If you turn on {-# LANGUAGE OverlappingInstances, IncoherentInstances #-}, etc. to make it compile, you will get not-so-subtle failures when you go to write modules that import the module that provides this definition and need to use any other Show instance. Ultimately you'll be able to get this code to compile with enough extensions, but it sadly will not do what you think it should do!
If you think about it given:
instance MyClass a => Show a where
show = myShow
instance HisClass a => Show a where
show = hisShow
which should the compiler pick?
Your module may only define one of these, but end user code will import a bunch of modules, not just yours. Also, if another module defines
instance Show HisDataTypeThatHasNeverHeardOfMyClass
the compiler would be well within its rights to ignore his instance and try to use yours.
The right answer, sadly, is to do two things.
For each individual instance of MyClass you can define a corresponding instance of Show with the very mechanical definition
instance MyClass Foo where ...
instance Show Foo where
show = myShow
This is fairly unfortunate, but works well when there are only a few instances of MyClass under consideration.
When you have a large number of instances, the way to avoid code-duplication (for when the class is considerably more complicated than show) is to define.
newtype WrappedMyClass a = WrapMyClass { unwrapMyClass :: a }
instance MyClass a => Show (WrappedMyClass a) where
show (WrapMyClass a) = myShow a
This provides the newtype as a vehicle for instance dispatch. and then
instance Foo a => Show (WrappedFoo a) where ...
instance Bar a => Show (WrappedBar a) where ...
is unambiguous, because the type 'patterns' for WrappedFoo a and WrappedBar a are disjoint.
There are a number of examples of this idiom running around in the the base package.
In Control.Applicative there are definitions for WrappedMonad and WrappedArrow for this very reason.
Ideally you'd be able to say:
instance Monad t => Applicative t where
pure = return
(<*>) = ap
but effectively what this instance is saying is that every Applicative should be derived by first finding an instance for Monad, and then dispatching to it. So while it would have the intention of saying that every Monad is Applicative (by the way the implication-like => reads) what it actually says is that every Applicative is a Monad, because having an instance head 't' matches any type. In many ways, the syntax for 'instance' and 'class' definitions is backwards.
(Edit: leaving the body for posterity, but jump to the end for the real solution)
In the declaration instance MyClass a => Show a, let's examine the error "Constraint is no smaller than the instance head." The constraint is the type class constraint to the left of '=>', in this case MyClass a. The "instance head" is everything after the class you're writing an instance for, in this case a (to the right of Show). One of the type inference rules in GHC requires that the constraint have fewer constructors and variables than the head. This is part of what are called the 'Paterson Conditions'. These exist as a guarantee that type checking terminates.
In this case, the constraint is exactly the same as the head, i.e. a, so it fails this test. You can remove the Paterson condition checks by enabling UndecidableInstances, most likely with the {-# LANGUAGE UndecidableInstances #-} pragma.
In this case, you're essentially using your class MyClass as a typeclass synonym for the Show class. Creating class synonyms like this is one of the canonical uses for the UndecidableInstances extension, so you can safely use it here.
'Undecidable' means that GHC can't prove typechecking will terminate. Although it sounds dangerous, the worst that can happen from enabling UndecidableInstances is that the compiler will loop, eventually terminating after exhausting the stack. If it compiles, then obviously typechecking terminated, so there are no problems. The dangerous extension is IncoherentInstances, which is as bad as it sounds.
Edit: another problem made possible by this approach arises from this situation:
instance MyClass a => Show a where
data MyFoo = MyFoo ... deriving (Show)
instance MyClass MyFoo where
Now there are two instances of Show for MyFoo, the one from the deriving clause and the one for MyClass instances. The compiler can't decide which to use, so it will bail out with an error message. If you're trying to make MyClass instances of types you don't control that already have Show instances, you'll have to use newtypes to hide the already-existing Show instances. Even types without MyClass instances will still conflict because the definition instance MyClass => Show a because the definition actually provides an implementation for all possible a (the context check comes in later; its not involved with instance selection)
So that's the error message and how UndecidableInstances makes it go away. Unfortunately it's a lot of trouble to use in actual code, for reasons Edward Kmett explains. The original impetus was to avoid specifying a Show constraint when there's already a MyClass constraint. Given that, what I would do is just use myShow from MyClass instead of show. You won't need the Show constraint at all.
I think it would be better to do it the other way around:
class Show a => MyClass a where
someFunc :: a -> a
myShow :: MyClass a => a -> String
myShow = show
You can compile it, but not with Haskell 98, You have to enable some language extensions :
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
-- at the top of your file
Flexible instances is there to allow context in instance declaration. I don't really know the meaning of UndecidableInstances, but I would avoid as much as I can.
As Ed Kmett pointed out, this is not possible at all for your case. If however you have access to the class you want to provide a default instance for, you can reduce the boilerplate to a minimum with a default implementation and constrain the input type with the default signature you need:
{-# LANGUAGE DefaultSignatures #-}
class MyClass a where
someFunc :: a -> Int
class MyShow a where
myShow :: a -> String
default myShow :: MyClass a => a -> String
myShow = show . someFunc
instance MyClass Int where
someFunc i = i
instance MyShow Int
main = putStrLn (myShow 5)
Note that the only real boilerplate (well, apart from the whole example) reduced to instance MyShow Int.
See aesons ToJSON for a more realistic example.
You may find some interesting answers in a related SO question: Linking/Combining Type Classes in Haskell

Resources