The codes looks like this:
class MyAnd a where
myAnd :: (Show a) => a -> a -> String
x `myAnd` y = (show x) ++ " and " ++ (show y)
data TrafficLight = Red | Yellow | Green deriving(Show, MyAnd)
Here MyAnd is a type class which has a function myAnd, I thought it is generic and the only constraint is the a has to has an instance of Show class..
In the TrafficLight type, it already derived from Show type class. However, when I compiled the codes, the compiler complains
Can't make a derived instance of ‘MyAnd TrafficLight’:
‘MyAnd’ is not a derivable class
In the data declaration for ‘TrafficLight’
Failed, modules loaded: none.
Does anyone have ideas about this?
You can't use deriving with user-defined classes. Usually deriving automatically generates code for the given class's methods, which is only possible because the compiler knows what the methods are supposed to do and can thus generate suitable implementations based on your type's structure. This is obviously not possible for user-defined classes as the compiler has no way of knowing how the methods are supposed to behave.
In your case it looks like all you want is to use the default implementations of the one method your class has, so no implementation would need to be generated by the compiler. Of course that means that deriving isn't necessary at all and you can just use an instance declaration without a body.
PS: If you'll always want to use the default implementation of the method, it might make the most sense not to use a class at all, but just define myAnd as a function.
For this specific problem, you can simply avoid defining a custom class:
data TrafficLight = Red | Yellow | Green deriving Show
myAnd :: (Show a) => a -> a -> String
x `myAnd` y = (show x) ++ " and " ++ (show y)
Now, myAnd is applicable to TrafficLights (as well as all the other Showable types).
Found this question while trying to figure out how to use GHC's DeriveAnyClass extension, which had only been out for three weeks back when this was asked.
Using it, the following works as you'd expect:
{-# LANGUAGE DeriveAnyClass #-}
class Show a => MyAnd a where
myAnd :: a -> a -> String
x `myAnd` y = (show x) ++ " and " ++ (show y)
data TrafficLight = Red | Yellow | Green deriving (Show, MyAnd)
Should be used with caution though, as it will literally derive any class, creating empty instances when necessary.
Related
While I was writing a small example of the Show instance, I had made an indentation error:
module Main where
data B= B0|B1
instance Show B where
show B0="0"
show B1="1"
main=print B0
Where, clearly, the working code is:
module Main where
data B= B0|B1
instance Show B where
show B0="0"
show B1="1"
main=print B0
I was expecting to get a compile error on the first one, but instead I could run it and it ended up in:
example.hs: stack overflow
Why does this code even compile?
Also, why is this a runtime error only (which, if stack is unconstrained, fills up your RAM) and not a compilation error?
The body of an instance can be empty. You can leave out the where clause:
instance Show B
but you can also include it:
instance Show B where
-- nothing here
This can be useful for type classes that provide default implementations for the methods, perhaps based on generic programming facilities. For example, with the aeson package, the usual way of defining instances to convert to and from JSON is to use generics and empty instances:
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
data Person = Person {
name :: Text
, age :: Int
} deriving (Generic, Show)
-- these empty instances use Generics to provide a default implementation
instance ToJSON Person
instance FromJSON Person
In your program, by leaving out the indentation, you've defined an instance Show B with no method definitions (and -Wall would generate a "missing method" warning telling you that it did not meet the minimal requirements for the instance). The unindented show is providing a new top-level definition for show, unrelated to the show in the Show type class.
You haven't used show explicitly. Instead, you've used it implicitly via print, which always calls the show from the type class, ignoring your top-level definition, so your crashing program is equivalent to:
data B = B0 | B1
instance Show B
main = print B0
This generates a stack overflow because there are default definitions of show and showsPrec that are used when no specific instances are given:
show x = shows x ""
showsPrec _ x s = show x ++ s
which operate together with the top-level function shows (not part of the type class):
shows = showsPrec 0
This works great when at least one of show or showsPrec is defined in the instance, and then the other gets a sensible definition, but if neither is defined, this creates an infinite recursive loop between these three functions.
Also, note that the following program would tell you show was ambiguous which would make it clearer what was going on.
module Main where
data B= B0|B1
instance Show B where
show B0="0"
show B1="1"
main=putStrLn (show B0) -- instead of print
Since you did not indent show, it means this does not belong to the instance for Show, you program is thus equivalent to:
instance Show B where -- ← no implementations
show B0 = "0"
show B1 = "1"
You here thus construct another function show, that has nothing to do with the Show typeclass, but simply has the same name.
Show defines three functions showsPrec :: Show a => Int -> a -> String -> String, show :: a -> String -> String, and showList :: [a] -> String -> String. showsPrec is often used since it has a precedence system to use parenthesis.
As a result show is impelemented in terms of showsPrec and showsPrec is implemented in terms of show:
class Show a where
{-# MINIMAL showsPrec | show #-}
-- …
showsPrec :: Int
-> a
-> ShowS
-- …
show :: a -> String
-- …
showList :: [a] -> ShowS
showsPrec _ x s = show x ++ s
show x = shows x ""
showList ls s = showList__ shows ls s
-- …
shows :: (Show a) => a -> ShowS
shows = showsPrec 0
It is thus sufficient to implement showsPrec or show, that is why there is a {-# MINIMUM showsPrec | show #-} pragma at the top of the type class.
If you do not implement any of the two, then the compiler will raise a warning, and use thus the basic implementations, but that will lead to nothing, since show will call showPrec, which will then call show, until eventually the stack is exhausted.
I am working with so-called tokens which are tuples with a string and a tag that I wish I could render on the screen in the following format: [TAG: VALUE] I cannot do that because I am not doing something right. Here is the setup:
type Token value tag = ([value], tag)
data Tag = Whitespace | Alpha | Digit | Punctuation | Terminal
instance Show Tag where
show Alpha = "A"
show Whitespace = "W"
show Digit = "D"
show Punctuation = "P"
show Terminal = "|"
type TextToken = Token Char Tag
instance Show TextToken where
show (values, tag) = "[" ++ show tag ++ ": " ++ values ++ "]"
Which crashes at compiling:
Illegal instance declaration for `Show TextToken'
(All instance types must be of the form (T t1 ... tn)
where T is not a synonym.
Use -XTypeSynonymInstances if you want to disable this.)
In the instance declaration for `Show TextToken'
Then I tried replacing the instance with the following:
instance Show ([Char], Tag) where
show (values, tag) = "[" ++ show tag ++ ": " ++ values ++ "]"
And got the same problem again:
Illegal instance declaration for `Show ([Char], Tag)'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `Show ([Char], Tag)'
Is there a way to make it work?
You'll want to use a newtype
newtype Tag a b = Tag (a, b)
instance (Show a, Show b) => Show (Tag a b) where
show (Tag (a, b)) = "[" ++ show a ++ ": " ++ show b ++ "]"
You're running into several instance resolution quibbles all at once.
Without the {-# LANGUAGE TypeSynonymInstances #-} pragma, you cannot use type synonyms in instance definitions... even if they're perfectly clear. Enabling it is fine, it's simply not Haskell 98.
When using complex, nested, or multiparameter types in instance definitions, you frequently run afoul of the overly restrictive Haskell 98 instance definition. In many cases this is fine, so enabling the {-# LANGUAGE FlexibleInstances #-} pragma will allow these OK opportunities.
Finally, dangerously, there's already a Show instance for ([Char], Tag), the polymorphic one instance Show (a, b) with a ~ [Char] and b ~ Tag. This means you'll run afoul of the OverlappingInstances warning.
You can disable this by telling GHC to allow OverlappingInstances using another pragma {-# LANGUAGE OverlappingInstances #-} but since it can cause very strange runtime behavior for both yourself and others who use your code, its use is highly discouraged.
Generally, if you're trying to "specialize" an instance declaration to a particular type, you need the general case to not exist.
newtype Tup a b = Tup (a, b)
instance Show (Tup Int Int) where
show (Tup tup) = show tup
instance Show (Tup String Int) where
show (Tup (s, int)) = s ++ ": " ++ show int
>>> show ("foo", 3)
foo: 3
>>> show (2, 3)
(2, 3)
>>> show ("foo", "bar")
No instance for...
The thing that you really need to decide is if you want different instances for different sorts of Token. If you do, then use a newtype (or compiler option, as some suggest). If you don't, then make Token a data and define your instance on the generic Token type.
To make a newtype wrapper:
newtype TextToken = TextToken (Token Char Tag)
then declaring the Show instance for the wrapper:
instance Show TextToken where
In your case I'd still recommend changing
type Token value tag = ([value], tag)
to
data Token value tag = Token [value] tag
because you have a record type anyway, so you might as well make it explicit.
data A = Num Int
| Fun (A -> A) String deriving Show
instance Show (Fun (A -> A) String) where
show (Fun f s) = s
I would like to have an attribute for a function A -> A to print it, therefore there is a String type parameter to Fun. When I load this into ghci, I get
/home/kmels/tmp/show-abs.hs:4:16:
Not in scope: type constructor or class `Fun'
I guess this could be achieved by adding a new data type
data FunWithAttribute = FA (A -> A) String
adding data A = Num Int | Fun FunWithAttribute and writing an instance Show FunWithAttribute. Is the additional data type avoidable?
Instances are defined for types as a whole, not individual constructors, which is why it complains about Fun not being a type.
I assume your overall goal is to have a Show instance for A, which can't be derived because functions can't (in general) have a Show instance. You have a couple options here:
Write your own Show instance outright:
That is, something like:
instance Show A where
show (Num n) = "Num " ++ show n
show (Fun _ s) = s
In many cases, this makes the most sense. But sometimes it's nicer to derive Show, especially on complex recursive types where only one case of many is not automatically Show-able.
Make A derivable:
You can only derive Show for types that contain types that themselves have Show instances. There's no instance for A -> A, so deriving doesn't work. But you can write one that uses a placeholder of some sort:
instance Show (A -> A) where
show _ = "(A -> A)"
Or even just an empty string, if you prefer.
Note that this requires the FlexibleInstances language extension; it's one of the most harmless and commonly used extensions, is supported by multiple Haskell implementations, and the restrictions it relaxes are (in my opinion) a bit silly to begin with, so there's little reason to avoid it.
An alternate approach would be to have a wrapper type, as you mention in the question. You could even make this more generic:
data ShowAs a = ShowAs a String
instance Show (ShowAs a) where
show (ShowAs _ s) = s
...and then use (ShowAs (A -> A)) in the Fun constructor. This makes it a bit awkward by forcing you to do extra pattern matching any time you want to use the wrapped type, but it gives you lots of flexibility to "tag" stuff with how it should be displayed, e.g. showId = id `ShowAs` "id" or suchlike.
Perhaps I'm not following what you are asking for. But the above code could be written like this in order to compile:
data A = Num Int
| Fun (A -> A) String
instance Show A where
show (Fun f s) = s
show (Num i) = show i
Some explanation
It looked like you were trying to write a show instance for a constructor (Fun). Class instances are written for the entire data type (there might be exceptions, dunno). So you need to write one show matching on each constructor as part of the instance. Num and Fun are each constructors of the data type A.
Also, deriving can't be used unless each parameter of each constructor is, in turn, member of, in this case, Show. Now, your example is a bit special since it wants to Show (A -> A). How to show a function is somewhat explained in the other responses, although I don't think there is an exhaustive way. The other examples really just "show" the type or some place holder.
A Show instance (or any class instance) needs to be defined for a data type, not for a type constructor. That is, you need simply
instance Show A where
Apparently, you're trying to get this instance with the deriving, but that doesn't work because Haskell doesn't know how to show A->A. Now it seems you don't even want to show that function, but deriving Show instances always show all available information, so you can't use that.
The obvious, and best, solution to your problem is worldsayshi's: don't use deriving at all, but define a proper instance yourself. Alternatively, you can define a pseudo-instance for A->A and then use deriving:
{-# LANGUAGE FlexibleInstances #-}
data A = Num Int | Fun (A->A) String deriving(Show)
instance Show (A->A) where show _ = ""
This works like
Prelude> Fun (const $ Num 3) "bla"
Fun "bla"
How do I write something like the following in Haskell:
showSquare :: (Show a, Num a) => a -> String
showSquare x = "The square of " ++ (show x) ++ " is " ++ (show (x * x))
showSquare :: (Show a, not Num a) => a -> String
showSquare x = "I don't know how to square " ++ (show x)
Basically, something like boost::enable_if in C++.
GHC extensions are ok.
Why would you want this? The typechecker makes sure that you will never call showSquare on something which isn't a Num in the first case. There is no instanceof in Haskell, as everything is typed statically.
It doesn't work for arbitrary types: you can only define your own type class, e.g.
class Mine a where
foo :: a -> String
instance (Num a) => Mine a where
foo x = show x*x
And you can add more instances for other classes, but you won't be able to write just instance Mine a for an arbitrary a. An additional instance (Show a) => ... will also not help, as overlapping instances are also not allowed (the link describes a way to work around it, but it requires quite a bit of additional machinery).
First, giving different type signature to different equations for the same function isn't possible at all. Any function can have only one type, regardless of how much equations it has.
Second, negative constraints does not (would not) have any sound meaning in Haskell. Recall what class constraint mean:
f :: Num a => a -> a -> a
f x y = x + y
Num a in the type of f means that we can apply any class methods of Num type class to values of type a. We are consciously not naming concrete type in order to get generic behavior. Essentially, we are saying "we do not care what a exactly is, but we do know that Num operations are applicable to it". Consequently, we can use Num methods on x and y, but no more than that, that is, we cannot use anything except for Num methods on x and y. This is what type class constraints are and why are they needed. They are specifying generic interface for the function.
Now consider your imaginary not Num a constraint. What information does this statement bring? Well, we know that a should not be Num. However, this information is completely useless for us. Consider:
f :: not Num a => a -> a
f = ???
What can you place instead of ???? Obviously, we know what we cannot place. But except for that this signature has no more information than
f :: a -> a
and the only operation f could be is id (well, undefined is possible too, but that's another story).
Finally consider your example:
showSquare :: (Show a, not Num a) => a -> String
showSquare x = "I don't know how to square " ++ (show x)
I do not give first part of your example intentionally, see the first sentence in my answer. You cannot have different equations with different types. But this function alone is completely useless. You can safely remove not Num a constraint here, and it won't change anything.
The only usage for such negative constrains in statically typed Haskell is producing compile-time errors when you supply, say, Int for not Num a-constrainted variable. But I see no use for this.
If I really, absolutely needed something like this (and I don't believe I ever have), I think this is the simplest approach in Haskell:
class Show a => ShowSquare a where
showSquare :: a -> String
showSquare a = "I don't know how to square " ++ (show a)
instance ShowSquare Int where
showSquare = showSquare'
instance ShowSquare Double where
showSquare = showSquare'
-- add other numeric type instances as necessary
-- make an instance for everything else
instance Show a => ShowSquare a
showSquare' :: (Show a, Num a) => a -> String
showSquare' x = "The square of " ++ (show x) ++ " is " ++ (show (x * x))
This requires overlapping instances, obviously. Some people may complain about the required boilerplate, but it's pretty minimal. 5 or 6 instances would cover most numeric numeric types.
You could probably make something work using ideas from the Advanced Overlap wiki page. Note that technique still requires instances to be listed explicitly, so whether it's better than this is probably a matter of taste.
It's also possible to approach the problem with template haskell, by writing a TH splice instead of a function. The splice would have to reify ''Num at the call site to determine if a Num instance is in scope, then choose the appropriate function. However, making this work is likely to be more trouble than just writing out the Num instances manually.
Depending on "not a Num a" is very fragile in Haskell in a way that is not fragile in C++.
In C++ the classes are defined in one placed (closed) while Haskell type classes are open and can have instances declared in module C of data from module A and class from module B.
The (no extension) resolution of type classes has a guiding principle that importing a module like "C" would never change the previous resolution of type classes.
Code that expected "not a Num Custom" will change if any recursively imported module (e.g. from another package) defined an "instance Num Custom".
There is an additional problem with polymorphism. Consider a function in module "D"
useSS :: Show a => a -> Int -> [String]
useSS a n = replicate n (showSquare a)
data Custom = Custom deriving Show
use1 :: Int -> String
use1 = useSS Custom -- no Num Custom in scope
Now consider a module "E" in another package which imports the above module "D"
instance Num Custom
use2 :: Int -> String
use2 = useSS Custom -- has a Num Custom now
What should (use1 1) and (use2 1) evaluate to? Do you want to work with a language with traps like this? Haskell is trying to prevent, by principled design, the existence of this trap.
This kind of ad hoc overloading is everywhere in C++ resolution but is exactly what Haskell was designed to avoid. It is possible with GHC extensions to do such things, but one has to be careful not to create dangerous traps, and it is not encouraged.
I'm a linguist working on the formal syntax/semantics of Natural Languages. I've started
using Haskell quite recently and very soon I realized that I needed to add subtyping. For example given the types Human
and Animal,
I would like to have Human as a subtype of Animal. I found that this is possible using a coerce function where the instances are declared by the user, but I do not know how to define coerce in the instances I'm interested in. So basically I do not know what to add after 'coerce =' to make it work'. Here is the code up to that point:
{-# OPTIONS
-XMultiParamTypeClasses
-XFlexibleInstances
-XFunctionalDependencies
-XRankNTypes
-XTypeSynonymInstances
-XTypeOperators
#-}
module Model where
import Data.List
data Animal = A|B deriving (Eq,Show,Bounded,Enum)
data Man = C|D|E|K deriving (Eq,Show,Bounded,Enum)
class Subtype a b where
coerce :: a->b
instance Subtype Man Animal where
coerce=
animal:: [Animal]
animal = [minBound..maxBound]
man:: [Man]
man = [minBound..maxBound]
Thanks in advance
Just ignore the Subtype class for a second and examine the type of the coerce function you are writing. If the a is a Man and the b is an Animal, then the type of the coerce function you are writing should be:
coerce :: Man -> Animal
This means that all you have to do is write a sensible function that converts each one of your Man constructors (i.e. C | D | E | K) to a corresponding Animal constructor (i.e. A | B). That's what it means to subtype, where you define some function that maps the "sub" type onto the original type.
Of course, you can imagine that because you have four constructors for your Man type and only two constructors for your Animal type then you will end up with more than one Man constructor mapping to the same Animal constructor. There's nothing wrong with that and it just means that the coerce function is not reversible. I can't comment more on that without knowing exactly what those constructors were meant to represent.
The more general answer to your question is that there is no way to automatically know which constructors in Man should map to which constructors in Animal. That's why you have to write the coerce function to tell it what the relationship between men and animals is.
Note also that there is nothing special about the 'Subtype' class and 'coerce' function. You can just skip them and write an 'manToAnimal' function. After all there is no built-in language or compiler support for sub-typing and Subtype is just another class that some random guy came up with (and frankly, subtyping is not really idiomatic Haskell, but you didn't really ask about that). All that defining the class instance does is allow you to overload the function coerce to work on the Man type.
I hope that helps.
What level of abstraction are you working where you "need to add subtyping"?
Are you trying to create world model for your program encoded by Haskell types? (I can see this if your types are actually Animal, Dog, etc.)
Are you trying to create more general software, and you think subtypes would be a good design?
Or are you just learning haskell and playing around with things.
If (1), I think that will not work out for you so well. Haskell does not have very good reflective abilities -- i.e. ability to weave type logic into runtime logic. Your model would end up pretty deeply entangled with the implementation. I would suggest creaing a "world model" (set of) types, as opposed to a set of types corresponding to a specific world model. I.e., answer this question for Haskell: what is a world model?
If (2), think again :-). Subtyping is part of a design tradition in which Haskell does not participate. There are other ways to design your program, and they will end up playing nicer with the functional mindset then subtyping would have. It takes times to develop your functional design sense, so be patient with it. Just remember: keep it simple, stupid. Use data types and functions over them (but remember to use higher-order functions to generalize and share code). If you are reaching for advanced features (even typeclasses are fairly advanced in the sense I mean), you are probably doing it wrong.
If (3), see Doug's answer, and play with stuff. There are lots of ways to fake it, and they all kind of suck eventually.
I don't know much about Natural Languages so my suggestion may be missing the point, but this may be what you are looking for.
{-# OPTIONS
-XMultiParamTypeClasses
-XFlexibleContexts
#-}
module Main where
data Animal = Mammal | Reptile deriving (Eq, Show)
data Dog = Terrier | Hound deriving (Eq, Show)
data Snake = Cobra | Rattle deriving (Eq, Show)
class Subtype a b where
coerce :: a -> b
instance Subtype Animal Animal where
coerce = id
instance Subtype Dog Animal where
coerce _ = Mammal
instance Subtype Snake Animal where
coerce _ = Reptile
isWarmBlooded :: (Subtype a Animal) => a -> Bool
isWarmBlooded = (Mammal == ) . coerce
main = do
print $ isWarmBlooded Hound
print $ isWarmBlooded Cobra
print $ isWarmBlooded Mammal
Gives you:
True
False
True
Is that kind of what you are shooting for? Haskell doesn't have subtyping built-in, but this might do as a work-around. Admittedly, there are probably better ways to do this.
Note: This answer is not intended to point out the best, correct or idomatic way to solve the problem at hand. It is intended to answer the question which was "what to add after 'coerce=' to make it work."
You can't write the coerce function you're looking for — at least, not sensibly. There aren't any values in Animal that correspond with the values in Man, so you can't write a definition for coerce.
Haskell doesn't have subtyping as an explicit design decision, for various reasons (it allows type inference to work better, and allowing subtyping vastly complicates the language's type system). Instead, you should express relationships like this using aggregation:
data Animal = A | B | AnimalMan Man deriving (Eq, Show, Bounded, Enum)
data Man = C | D | E | K deriving (Eq, Show, Bounded, Enum)
AnimalMan now has the type Man -> Animal, exactly as you wanted coerce to have.
If I understood you correctly, it is quite possible. We will use type classes and generalized algebraic data types to implement this functionality.
If you want to be able to do something like this (where animals and humans can be fed but only humans can think):
animals :: [AnyAnimal]
animals = (replicate 5 . AnyAnimal $ SomeAnimal 10) ++ (replicate 5 . AnyAnimal $ SomeHuman 10 10)
humans :: [AnyHuman]
humans = replicate 5 . AnyHuman $ SomeHuman 10 10
animals' :: [AnyAnimal]
animals' = map coerce humans
animals'' :: [AnyAnimal]
animals'' = (map (\(AnyAnimal x) -> AnyAnimal $ feed 50 x) animals) ++
(map (\(AnyAnimal x) -> AnyAnimal $ feed 50 x) animals') ++
(map (\(AnyHuman x) -> AnyAnimal $ feed 50 x) humans)
humans' :: [AnyHuman]
humans' = (map (\(AnyHuman x) -> AnyHuman . think 100 $ feed 50 x) humans)
Then it's possible, for example:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
-- | The show is there only to make things easier
class (Show a) => IsAnimal a where
feed :: Int -> a -> a
-- other interface defining functions
class (IsAnimal a) => IsHuman a where
think :: Int -> a -> a
-- other interface defining functions
class Subtype a b where
coerce :: a -> b
data AnyAnimal where
AnyAnimal :: (IsAnimal a) => a -> AnyAnimal
instance Show AnyAnimal where
show (AnyAnimal x) = "AnyAnimal " ++ show x
data AnyHuman where
AnyHuman :: (IsHuman a) => a -> AnyHuman
instance Show AnyHuman where
show (AnyHuman x) = "AnyHuman " ++ show x
data SomeAnimal = SomeAnimal Int deriving Show
instance IsAnimal SomeAnimal where
feed = flip const
data SomeHuman = SomeHuman Int Int deriving Show
instance IsAnimal SomeHuman where
feed = flip const
instance IsHuman SomeHuman where
think = flip const
instance Subtype AnyHuman AnyAnimal where
coerce (AnyHuman x) = AnyAnimal x
animals :: [AnyAnimal]
animals = (replicate 5 . AnyAnimal $ SomeAnimal 10) ++ (replicate 5 . AnyAnimal $ SomeHuman 10 10)
humans :: [AnyHuman]
humans = replicate 5 . AnyHuman $ SomeHuman 10 10
animals' :: [AnyAnimal]
animals' = map coerce humans
Few comments:
You can make AnyAnimal and AnyHuman instances of their respective classes for convenience (atm. you have to unpack them first and pack them afterwards).
We could have single GADT AnyAnimal like this (both approaches have their use I would guess):
data AnyAnimal where
AnyAnimal :: (IsAnimal a) => a -> AnyAnimal
AnyHuman :: (IsHuman a) => a -> AnyAnimal
instance Show AnyHuman where
show (AnyHuman x) = "AnyHuman " ++ show x
show (AnyAnimal x) = "AnyAnimal " ++ show x
instance Subtype AnyAnimal AnyAnimal where
coerce (AnyHuman x) = AnyAnimal x
coerce (AnyAnimal x) = AnyAnimal x
It's rather advanced, but have a look at Edward Kmett's work on using the new Constraint kinds for this kind of functionality.