GHC doesn't pick the only available instance - haskell

I'm trying to write a CSS DSL in Haskell, and keep the syntax as close to CSS as possible. One difficulty is that certain terms can appear both as a property and value. For example flex: you can have "display: flex" and "flex: 1" in CSS.
I've let myself inspire by the Lucid API, which overrides functions based on the function arguments to generate either attributes or DOM nodes (which sometimes also share names, eg <style> and <div style="...">).
Anyway, I've ran into a problem that GHC fails to typecheck the code (Ambiguous type variable), in a place where it is supposed to pick one of the two available typeclass instances. There is only one instance which fits (and indeed, in the type error GHC prints "These potential instance exist:" and then it lists just one). I'm confused that given the choice of a single instance, GHC refuses to use it. Of course, if I add explicit type annotations then the code compiles. Full example below (only dependency is mtl, for Writer).
{-# LANGUAGE FlexibleInstances #-}
module Style where
import Control.Monad.Writer.Lazy
type StyleM = Writer [(String, String)]
newtype Style = Style { runStyle :: StyleM () }
class Term a where
term :: String -> a
instance Term String where
term = id
instance Term (String -> StyleM ()) where
term property value = tell [(property, value)]
display :: String -> StyleM ()
display = term "display"
flex :: Term a => a
flex = term "flex"
someStyle :: Style
someStyle = Style $ do
flex "1" -- [1] :: StyleM ()
display flex -- [2]
And the error:
Style.hs:29:5: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘flex’
prevents the constraint ‘(Term
([Char]
-> WriterT
[(String, String)]
Data.Functor.Identity.Identity
a0))’ from being solved.
(maybe you haven't applied a function to enough arguments?)
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instance exist:
one instance involving out-of-scope types
instance Term (String -> StyleM ()) -- Defined at Style.hs:17:10
• In a stmt of a 'do' block: flex "1"
In the second argument of ‘($)’, namely
‘do { flex "1";
display flex }’
In the expression:
Style
$ do { flex "1";
display flex }
Failed, modules loaded: none.
I've found two ways how to make this code compile, none of which I'm happy with.
Add explicit annotation where the flex function is used ([1]).
Move the line where flex is used to the end of the do block (eg. comment out [2]).
One difference between my API and Lucid is that the Lucid terms always take one argument, and Lucid uses fundeps, which presumably gives the GHC typechecker more information to work with (to choose the correct typeclass instance). But in my case the terms don't always have an argument (when they appear as the value).

The problem is that the Term instance for String -> StyleM () only exists when StyleM is parameterized with (). But in a do-block like
someStyle :: Style
someStyle = Style $ do
flex "1"
return ()
there is not enough information to know which is the type parameter in flex "1", because the return value is thrown away.
A common solution to this problem is the "constraint trick". It requires type equality constraints, so you have to enable {-# LANGUAGE TypeFamilies #-}
or {-# LANGUAGE GADTs #-} and tweak the instance like this:
{-# LANGUAGE TypeFamilies #-}
instance (a ~ ()) => Term (String -> StyleM a) where
term property value = tell [(property, value)]
This tells the compiler: "You don't need to know the precise type a to get the instance, there is one for all types! However, once the instance is determined, you'll always find that the type was () after all!"
This trick is the typeclass version of Henry Ford's "You can have any color you like, as long as it's black." The compiler can find an instance despite the ambiguity, and finding the instance gives him enough information to resolve the ambiguity.
It works because Haskell's instance resolution never backtracks, so once an instance "matches", the compiler has to commit to any equalities it discovers in the preconditions of the instance declaration, or throw a type error.

There is only one instance which fits (and indeed, in the type error GHC prints "These potential instance exist:" and then it lists just one). I'm confused that given the choice of a single instance, GHC refuses to use it.
Type classes are open; any module could define new instances. So GHC never assumes that it knows about all instances, when checking a use of a type class. (With the possible exception of the bad extensions like OverlappingInstances.) Logically, then, the only possible answers to a question "is there an instance for C T" are "yes" and "I don't know". To answer "no" risks incoherence with another part of your program that does define an instance C T.
So, you should not imagine the compiler iterating over every declared instance and seeing whether it fits at the particular use site of interest, because what would it do with all the "I don't know"s? Instead, the process works like this: infer the most general type that could be used at the particular use site and query the instance store for the needed instance. The query can return a more general instance than the one needed, but it can never return a more specific instance, since it would have to choose which more specific instance to return; then your program is ambiguous.
One way to think about the difference is that iterating over all declared instances for C would take linear time in the number of instances, while querying the instance store for a specific instance only has to examine a constant number of potential instances. For example, if I want to type check
Left True == Left False
I need an instance for Eq (Either Bool t), which can only be satisfied by one of
instance Eq (Either Bool t)
instance Eq (Either a t) -- *
instance Eq (f Bool t)
instance Eq (f a t)
instance Eq (g t)
instance Eq b
(The instance marked * is the one that actually exists, and in standard Haskell (without FlexibleInstances) it's the only one of these instances that is legal to declare; the traditional restriction to instances of the form C (T var1 ... varN) makes this step easy since there will always be exactly one potential instance.)
If instances are stored in something like a hash table then this query can be done in constant time regardless of the number of declared instances of Eq (which is probably a pretty large number).
In this step, only instance heads (the stuff to the right of the =>) are examined. Along with a "yes" answer, the instance store can return new constraints on type variables that come from the context of the instance (the stuff to the left of the =>). These constraints then need to be solved in the same manner. (This is why instances are considered to overlap if they have overlapping heads, even if their contexts look mutually exclusive, and why instance Foo a => Bar a is almost never a good idea.)
In your case, since a value of any type can be discarded in do notation, we need an instance for Term (String -> StyleM a). The instance Term (String -> StyleM ()) is more specific, so it's useless in this case. You could either write
do
() <- flex "1"
...
to make the needed instance more specific, or make the provided instance more general by using the type equality trick as explained in danidiaz's answer.

Related

Can we tweak "a -> a" function in Haskell?

In Haskell id function is defined on type level as id :: a -> a and implemented as just returning its argument without any modification, but if we have some type introspection with TypeApplications we can try to modify values without breaking type signature:
{-# LANGUAGE AllowAmbiguousTypes, ScopedTypeVariables, TypeApplications #-}
module Main where
class TypeOf a where
typeOf :: String
instance TypeOf Bool where
typeOf = "Bool"
instance TypeOf Char where
typeOf = "Char"
instance TypeOf Int where
typeOf = "Int"
tweakId :: forall a. TypeOf a => a -> a
tweakId x
| typeOf #a == "Bool" = not x
| typeOf #a == "Int" = x+1
| typeOf #a == "Char" = x
| otherwise = x
This fail with error:
"Couldn't match expected type ‘a’ with actual type ‘Bool’"
But I don't see any problems here (type signature satisfied):
My question is:
How can we do such a thing in a Haskell?
If we can't, that is theoretical\philosophical etc reasons for this?
If this implementation of tweak_id is not "original id", what are theoretical roots that id function must not to do any modifications on term level. Or can we have many implementations of id :: a -> a function (I see that in practice we can, I can implement such a function in Python for example, but what the theory behind Haskell says to this?)
You need GADTs for that.
{-# LANGUAGE ScopedTypeVariables, TypeApplications, GADTs #-}
import Data.Typeable
import Data.Type.Equality
tweakId :: forall a. Typeable a => a -> a
tweakId x
| Just Refl <- eqT #a #Int = x + 1
-- etc. etc.
| otherwise = x
Here we use eqT #type1 #type2 to check whether the two types are equal. If they are, the result is Just Refl and pattern matching on that Refl is enough to convince the type checker that the two types are indeed equal, so we can use x + 1 since x is now no longer only of type a but also of type Int.
This check requires runtime type information, which we usually do not have due to Haskell's type erasure property. The information is provided by the Typeable type class.
This can also be achieved using a user-defined class like your TypeOf if we make it provide a custom GADT value. This can work well if we want to encode some constraint like "type a is either an Int, a Bool, or a String" where we statically know what types to allow (we can even recursively define a set of allowed types in this way). However, to allow any type, including ones that have not yet been defined, we need something like Typeable. That is also very convenient since any user-defined type is automatically made an instance of Typeable.
This fail with error: "Couldn't match expected type ‘a’ with actual type ‘Bool’"But I don't see any problems here
Well, what if I add this instance:
instance TypeOf Float where
typeOf = "Bool"
Do you see the problem now? Nothing prevents somebody from adding such an instance, no matter how silly it is. And so the compiler can't possibly make the assumption that having checked typeOf #a == "Bool" is sufficient to actually use x as being of type Bool.
You can squelch the error if you are confident that nobody will add malicious instances, by using unsafe coercions.
import Unsafe.Coerce
tweakId :: forall a. TypeOf a => a -> a
tweakId x
| typeOf #a == "Bool" = unsafeCoerce (not $ unsafeCoerce x)
| typeOf #a == "Int" = unsafeCoerce (unsafeCoerce x+1 :: Int)
| typeOf #a == "Char" = unsafeCoerce (unsafeCoerce x :: Char)
| otherwise = x
but I would not recommend this. The correct way is to not use strings as a poor man's type representation, but instead the standard Typeable class which is actually tamper-proof and comes with suitable GADTs so you don't need manual unsafe coercions. See chi's answer.
As an alternative, you could also use type-level strings and a functional dependency to make the unsafe coercions safe:
{-# LANGUAGE DataKinds, FunctionalDependencies
, ScopedTypeVariables, UnicodeSyntax, TypeApplications #-}
import GHC.TypeLits (KnownSymbol, symbolVal)
import Data.Proxy (Proxy(..))
import Unsafe.Coerce
class KnownSymbol t => TypeOf a t | a->t, t->a
instance TypeOf Bool "Bool"
instance TypeOf Int "Int"
tweakId :: ∀ a t . TypeOf a t => a -> a
tweakId x = case symbolVal #t Proxy of
"Bool" -> unsafeCoerce (not $ unsafeCoerce x)
"Int" -> unsafeCoerce (unsafeCoerce x + 1 :: Int)
_ -> x
The trick is that the fundep t->a makes writing another instance like
instance TypeOf Float "Bool"
a compile error right there.
Of course, really the most sensible approach is probably to not bother with any kind of manual type equality at all, but simply use the class right away for the behaviour changes you need:
class Tweakable a where
tweak :: a -> a
instance Tweakable Bool where
tweak = not
instance Tweakable Int where
tweak = (+1)
instance Tweakable Char where
tweak = id
The other answers are both very good for covering the ways you can do something like this in Haskell. But I thought it was worth adding something speaking more to this part of the question:
If we can't, that is theoretical\philosophical etc reasons for this?
Actually Haskellers do generally rely quite strongly on the theory that forbids something like your tweakId from existing with type forall a. a -> a. (Even though there are ways to cheat, using things like unsafeCoerce; this is usually considered bad style if you haven't done something like in leftaroundabout's answer, where a class with functional dependencies ensures the unsafe coerce is always valid)
Haskell uses parametric polymorphism1. That means we can write code that works on multiple types because it will treat them all the same; the code only uses operations that will work regardless of the specific type it is invoked on. This is expressed in Haskell types by using type variables; a function with a variable in its type can be used with any type at all substituted for the variable, because every single operation in the function definition will work regardless of what type is chosen.
About the simplest example is indeed the function id, which might be defined like this:
id :: forall a. a -> a
id x = x
Because it's parametrically polymorphic, we can simply choose any type at all we like and use id as if it was defined on that type. For example as if it were any of the following:
id :: Bool -> Bool
id x = x
id :: Int -> Int
id x = x
id :: Maybe (Int -> [IO Bool]) -> Maybe (Int -> [IO Bool])
id x = x
But to ensure that the definition does work for any type, the compiler has to check a very strong restriction. Our id function can only use operations that don't depend on any property of any specific type at all. We can't call not x because the x might not be a Bool, we can't call x + 1 because the x might not be a number, can't check whether x is equal to anything because it might not be a type that supports equality, etc, etc. In fact there is almost nothing you can do with x in the body of id. We can't even ignore x and return some other value of type a; this would require us to write an expression for a value that can be of any type at all and the only things that can do that are things like undefined that don't evaluate to a value at all (because they throw exceptions). It's often said that in fact there is only one valid function with type forall a. a -> a (and that is id)2.
This restriction on what you can do with values whose type contains variables isn't just a restriction for the sake of being picky, it's actually a huge part of what makes Haskell types useful. It means that just looking at the type of a function can often tell you quite a bit about what it can possibly do, and once you get used to it Haskellers rely on this kind of thinking all the time. For example, consider this function signature:
map :: forall a b. (a -> b) -> [a] -> [b]
Just from this type (and the assumption that the code doesn't do anything dumb like add in extra undefined elements of the list) I can tell:
All of the items in the resulting list come are results of the function input; map will have no other way of producing values of type b to put in the list (except undefined, etc).
All of the items in the resulting list correspond to something in the input list mapped through the function; map will have no way of getting any a values to feed to the function (except undefined, etc)
If any items of the input list are dropped or re-ordered, it will be done in a "blind" way that isn't considering the elements at all, only their position in the list; map ultimately has no way of testing any property of the a and b values to decide which order they should go in. For example it might leave out the third element, or swap the 2nd and 76th elements if there are at least 100 elements, etc. But if it applies rules like that it will have to always apply them, regardless of the actual items in the list. It cannot e.g. drop the 4th element if it is less than the 5th element, or only keep outputs from the function that are "truthy", etc.
None of this would be true if Haskell allowed parametrically polymorphic types to have Python-like definitions that check the type of their arguments and then run different code. Such a definition for map could check if the function is supposed to return integers and if so return [1, 2, 3, 4] regardless of the input list, etc. So the type checker would be enforcing a lot less (and thus catching fewer mistakes) if it worked this way.
This kind of reasoning is formalised in the concept of free theorems; it's literally possible to derive formal proofs about a piece of code from its type (and thus get theorems for free). You can google this if you're interested in further reading, but Haskellers generally use this concept informally rather doing real proofs.
Sometimes we do need non-parametric polymorphism. The main tool Haskell provides for that is type classes. If a type variable has a class constraint, then there will be an interface of class methods provided by that constraint. For example the Eq a constraint allows (==) :: a -> a -> Bool to be used, and your own TypeOf a constraint allows typeOf #a to be used. Type class methods do allow you to run different code for different types, so this breaks parametricity. Even just adding Eq a to the type of map means I can no longer assume property 3 from above.
map :: forall a b. Eq a => (a -> b) -> [a] -> [b]
Now map can tell whether some of the items in the original list are equal to each other, so it can use that to decide whether to include them in the result, and in what order. Likewise Monoid a or Monoid b would allow map to break the first two properties by using mempty :: a to produce new values that weren't in the list originally or didn't come from the function. If I add Typeable constraints I can't assume anything, because the function could do all of the Python-style checking of types to apply special-case logic, make use of existing values it knows about if a or b happen to be those types, etc.
So something like your tweakId cannot be given the type forall a. a -> a, for theoretical reasons that are also extremely practically important. But if you need a function that behaves like your tweakId adding a class constraint was the right thing to do to break out of the constraints of parametricity. However simply being able to get a String for each type isn't enough; typeOf #a == "Int" doesn't tell the type checker that a can be used in operations requiring an Int. It knows that in that branch the equality check returned True, but that's just a Bool; the type checker isn't able to reason backwards to why this particular Bool is True and deduce that it could only have happened if a were the type Int. But there are alternative constructs using GADTs that do give the type checker additional knowledge within certain code branches, allowing you to check types at runtime and use different code for each type. The class Typeable is specifically designed for this, but it's a hammer that completely bypasses parametricity; I think most Haskellers would prefer to keep more type-based reasoning intact where possible.
1 Parametric polymorphism is in contrast to class-based polymorphism you may have seen in OO languages (where each class says how a method is implemented for objects of that specific class), or ad-hoc polymophism (as seen in C++) where you simply define multiple definitions with the same name but different types and the types at each application determine which definition is used. I'm not covering those in detail, but the key distinction is both of them allow the definition to have different code for each supported type, rather than guaranteeing the same code will process all supported types.
2 It's not 100% true that there's only one valid function with type forall a. a -> a unless you hide some caveats in "valid". But if you don't use any unsafe features (like unsafeCoerce or the foreign language interface), then a function with type forall a. a -> a will either always throw an exception or it will return its argument unchanged.
The "always throws an exception" isn't terribly useful so we usually assume an unknown function with that type isn't going to do that, and thus ignore this possibility.
There are multiple ways to implement "returns its argument unchanged", like id x = head . head . head $ [[[x]]], but they can only differ from the normal id in being slower by building up some structure around x and then immediately tearing it down again. A caller that's only worrying about correctness (rather than performance) can treat them all the same.
Thus, ignoring the "always undefined" possibility and treating all of the dumb elaborations of id x = x the same, we come to the perspective where we can say "there's only one function with forall a. a -> a".

Haskell: Define Show function for a user defined type, which is defined by "type" key word

Let's say I have the type StrInt defined as below
type StrInt = (String, Int)
toStrInt:: Str -> Int -> StrInt
toStrInt str int = (str, int)
I want the Show function to work as below:
Input: show (toStrInt "Hello", 123)
Output: "Hello123"
I have tried to define show as below:
instance Show StrInt where
show (str, int) = (show str) ++ (show int)
But that gives me error:
Illegal instance declaration for ‘Show StrInt’
(All instance types must be of the form (T t1 ... tn)
where T is not a synonym.
Use TypeSynonymInstances if you want to disable this.)
In the instance declaration for ‘Show StrInt’
Any ideas on how to solve this issue?
Appreciate your help!
What you're trying to do is 1. not a good idea to start with, 2. conflicts with the already-existing Show instance and is therefore not possible without OverlappingInstances hackery (which is almost never a good idea), and 3. the error message you're getting is not related to these problems; other class-instances with the same message may be perfectly fine but of course require the extension that GHC asks about.
The Show class is not for generating arbitrary string output in whatever format you feel looks nice right now. That's the purpose of pretty-printing. Show instead is supposed to yield syntactically valid Haskell, like the standard instance does:
Prelude> putStrLn $ show (("Hello,"++" World!", 7+3) :: (String,Int))
("Hello, World!",10)
Prelude> ("Hello, World!",10) -- pasted back the previous output
("Hello, World!",10)
If you write any Show instance yourself, it should also have this property.
Again because (String, Int) already has a Show instance, albeit just one arising from more generic instances namely
instance (Show a, Show b) => Show (a,b)
instance Show a => Show [a]
instance Show Int
declaring a new instance for the same type results in a conflict. Technically speaking this could be circumvented by using an {-# OVERLAPPING #-} pragma, but I would strongly advise against this because doing that kind of thing can lead to very confusing behaviour down the line when instance resolution inexplicably changes based on how the types are presented.
Instead, when you really have a good reason to give two different instances to a type containing given data, the right thing to do is generally to make it a separate type (so it's clear that there will be different behaviour) which just happens to have the same components.
data StrInt' = StrInt String Int
instance Show StrInt' where
...
That actually compiles without any further issues or need for extensions. (Alternatively you can also use newtype StrInt = StrInt (String, Int), but that doesn't really buy you anything and just means you can't bring in record labels.)
Instances of the form instance ClassName TypeSynonym are possible too, and can sometimes make sense, but as GHC already informed you they require the TypeSynonymInstances extension or one that supersedes it. In fact TypeSynonymInstances is not enough if the synonym points to a composite type like a tuple, in that case you need FlexibleInstances (which includes TypeSynonymInstances), an extension I enable all of the time.
{-# LANGUAGE FlexibleInstances #-}
class C
type StrInt = (String, Int)
instance C StrInt

Interaction of multiple overlapping instances

The module Type.hs defines the homonym newtype and exports only its type constructor, but not the value constructor, to avoid exposing the detail; it also provides a constructor function makeType to balance the lack of value ctor. Why do I need to wrap a String in a new type? Because I want it to be more than a String; in my specific case, Type is actually called Line, and what corresponds to makeType enforces that it contains only one \n, as the last character. A newtype seemed the most obvious choice to me. If this is not the case, forgive me: I'm learning.
module Type (Type, makeType) where
newtype Type = Type String
makeType :: String -> Type
makeType = Type
In order to show a value of type Type the way I like (for instance, given my actual usecase of Line, I might want to represent \n with a nice unicode character, or with the sequence <NL>, or whatever), I created another module TypeShow.hs, which I later (in the attempt of doing what I'm describing) I edited by adding some pragmas. Why another module? Because I guess the way something works inside and the way I show it to screen are two separete aspects. Am I wrong?
{-# LANGUAGE FlexibleInstances #-}
module TypeShow () where
import Type
instance Show Type where
show = const "Type"
-- the following instance came later, see below why
instance {-# OVERLAPS #-} Show (Maybe Type) where
show (Just t) = show t
show _ = ""
Beside this pair of modules (which describe the core of Type, and how it should be shown), I created other similar pairs Type1/Type1Show, Type2/Type2Show, which all wrap a String to represent and show other String-like entities.
For other reasons, I also needed another type which wraps an optional value, which can be of type Type, Type1, or any other type, so I wrote this module
module Wrapper (Wrapper, makeWrapper, getInside) where
newtype Wrapper a = Wrapper { getInside :: Maybe a }
makeWrapper :: a -> Wrapper a
makeWrapper = Wrapper . Just
(In reality Wrapper actually wraps more than one Type value, but I'll avoid putting more details then necessary; if the following is stupid exactly because I'm wrapping only one Type value in Wrapper, then please consider it's wrapping more than one, in reality.) Again, here I tried to hide the details of Wrapper while providing makeWrapper to make one, and getInside to have a "controlled" access to its inside.
I also wanted to show this on screen, so I created a corresponding WrapperShow.hs module, so that Wrapper's show method relies on the content's show method.
module WrapperShow () where
import Wrapper
instance Show a => Show (Wrapper a) where
show = show . getInside
At this point, however, when the type a is a Maybe Type, I wanted to show the content of the Wrapper printing an empty string instead of Nothing, or the content of the Just; therefore I wrote the instance Show (Maybe Type) that I commented above.
Given this, Type "hello" and Just $ Type "hello" are both correcly shown as Type, but Wrapper $ Just $ Type "hello" is displayed as Just Type, just like it's using Maybe's original instance of Show, irrespective of the fact that for this specific type inside the Maybe (the Type) I've customized the Show instance.
In the Show instance declaration for Wrapper, we don't really know what a is. But apparently we must already choose what Show instance to use for the Maybe a. With the information available, the only instance that matches is the default one Show a => Show (Maybe a), which doesn't require a concrete a.
The GHC User Guide, in the section about overlapping instances, mentions the concept of "postponing" the choice of an instance:
That postpones the question of which instance to pick to the call site
for f by which time more is known about the type b. You can write this
type signature yourself if you use the FlexibleContexts extension.
and
Exactly the same situation can arise in instance declarations themselves [...] The solution is to postpone the choice by adding the constraint to the context of the instance declaration
We could try such a trick. Instead of requiring Show a, require the whole Show (Maybe a). Now the Show instance is taken as "given" and we don't make a local decision. I think this has the effect of delaying the selection of the Show (Maybe a) instance to call sites like print $ Wrapper $ Just $ Type 3, where we have more information about the concrete type of a.
Testing this hypothesis:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
newtype Type = Type Int
instance Show Type where
show = const "Type"
instance {-# OVERLAPS #-} Show (Maybe Type) where
show (Just t) = show t
show _ = ""
newtype Wrapper a = Wrapper (Maybe a)
instance Show (Maybe a) => Show (Wrapper a) where
show (Wrapper edit) = show edit
main :: IO ()
main = print $ Wrapper $ Just $ Type 3
-- output: Type
That said, I find this behavior confusing and would steer clear of it in production code.
As #dfeuer notes in a comment and linked code, the overlapping instance is problematic. For example, if we add this innocent function to the code of this answer:
foo :: Show a => Maybe a -> String
foo = show
The module ceases to compile:
* Overlapping instances for Show (Maybe a)
arising from a use of `show'
Matching instances:
instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
instance [overlap ok] Show (Maybe Type) -- Defined at Main.hs:14:27
(The choice depends on the instantiation of `a'
But now I'm confused. Why doesn't the exact same type error happen with the instance definition Show (Wrapper a) in the original question?
The reason foo fails to compile seems to be the last bullet point in the description of the instance search procedure:
Now find all instances, or in-scope given constraints, that unify with
the target constraint, but do not match it. [here, Show (Maybe Type)] Such non-candidate
instances might match when the target constraint is further
instantiated. If all of them are incoherent top-level instances, the
search succeeds, returning the prime candidate. Otherwise the search
fails.
[...]
The final bullet (about unifiying instances) makes GHC
conservative about committing to an overlapping instance. For example:
f :: [b] -> [b]
Suppose that from the RHS of f we get the
constraint C b [b]. But GHC does not commit to instance (C), because
in a particular call of f, b might be instantiated to Int, in which
case instance (D) would be more specific still. So GHC rejects the
program.
Perhaps—unlike normal functions—instance definitions are exempt from this particular rule, but I don't see that mentioned in the docs.

Function that behaves differently depending on which type classes the argument belong to

In Haskell, is there any way to declare function it behaves differently depending on whether the type of a argument is an instance of specific type class?
For example, can I define genericShow in the following example?
-- If type `a` is an instance of `Show`.
genericShow :: Show a => a -> String
genericShow = show
-- If type `a` is not an instance of `Show`.
genericShow :: a -> String
genericShow _ = "(Cannot be shown)"
> genericShow 3
"3"
> genericShow const
"(Cannot be shown)"
No.
The closest you can get is to use Overlapping instances, with a catch-all instance for anything not having a more specific Show instance.
instance {-# OVERLAPPABLE #-} Show a where
show _ = "(Cannot be shown)"
Overlapping instances come with lots of caveats: see topics like 'orphan instances', 'Incoherent instances'. That's particularly awkward with Prelude classes like Show, because there's likely to be lots of instances hidden away in libraries.
As #duplode says, there are many dangers. Almost certainly there's a better way to achieve whatever it is you think you want.

Why can't I use record selectors with an existentially quantified type?

When using Existential types, we have to use a pattern-matching syntax for extracting the foralled value. We can't use the ordinary record selectors as functions. GHC reports an error and suggest using pattern-matching with this definition of yALL:
{-# LANGUAGE ExistentialQuantification #-}
data ALL = forall a. Show a => ALL { theA :: a }
-- data ok
xALL :: ALL -> String
xALL (ALL a) = show a
-- pattern matching ok
-- ABOVE: heaven
-- BELOW: hell
yALL :: ALL -> String
yALL all = show $ theA all
-- record selector failed
forall.hs:11:19:
Cannot use record selector `theA' as a function due to escaped type variables
Probable fix: use pattern-matching syntax instead
In the second argument of `($)', namely `theA all'
In the expression: show $ theA all
In an equation for `yALL': yALL all = show $ theA all
Some of my data take more than 5 elements. It's hard to maintain the code if I
use pattern-matching:
func1 (BigData _ _ _ _ elemx _ _) = func2 elemx
Is there a good method to make code like that maintainable or to wrap it up so that I can use some kind of selectors?
Existential types work in a more elaborate manner than regular types. GHC is (rightly) forbidding you from using theA as a function. But imagine there was no such prohibition. What type would that function have? It would have to be something like this:
-- Not a real type signature!
theA :: ALL -> t -- for a fresh type t on each use of theA; t is an instance of Show
To put it very crudely, forall makes GHC "forget" the type of the constructor's arguments; all that the type system knows is that this type is an instance of Show. So when you try to extract the value of the constructor's argument, there is no way to recover the original type.
What GHC does, behind the scenes, is what the comment to the fake type signature above says—each time you pattern match against the ALL constructor, the variable bound to the constructor's value is assigned a unique type that's guaranteed to be different from every other type. Take for example this code:
case ALL "foo" of
ALL x -> show x
The variable x gets a unique type that is distinct from every other type in the program and cannot be matched with any type variable. These unique types are not allowed to escape to the top level—which is the reason why theA cannot be used as a function.
You can use record syntax in pattern matching,
func1 BigData{ someField = elemx } = func2 elemx
works and is much less typing for huge types.

Resources