When I specify x has type a, why does Haskell try to infer it has type a0? - haskell

Sometimes I'll specify something's type in a signature as, say, a, and GHC will respond that it can't deduce that its type is a0. Is there a single reason this happens, or a number of different possible reasons? Sometimes I solve it, sometimes not; I'm hoping for a unified theory.
Here's a short example. (To see this code including comments explaining what it's trying to do, see here.)
{-# LANGUAGE MultiParamTypeClasses
, AllowAmbiguousTypes
, FlexibleInstances
, GADTs #-}
type SynthName = String
data Synth format where
Synth :: SynthName -> Synth format
data MessageA format where
MessageA :: String -> MessageA format
data MessageB format where
MessageB :: String -> MessageB format
class (Message format) a where
theMessage :: a -> String
instance (Message format) (MessageA format) where
theMessage (MessageA msg) = msg
instance (Message format) (MessageB format) where
theMessage (MessageB msg) = msg
play :: Message format m => Synth format -> m -> IO ()
play (Synth name) msg =
print $ name ++ " now sounds like " ++ theMessage msg
That produces the following error.
riddles/gadt-forget/closest-to-vivid.hs:38:42: error:
• Could not deduce (Message format0 m)
arising from a use of ‘theMessage’
from the context: Message format m
bound by the type signature for:
play :: forall format m.
Message format m =>
Synth format -> m -> IO ()
at riddles/gadt-forget/closest-to-vivid.hs:36:1-54
The type variable ‘format0’ is ambiguous
Relevant bindings include
msg :: m (bound at riddles/gadt-forget/closest-to-vivid.hs:37:19)
play :: Synth format -> m -> IO ()
(bound at riddles/gadt-forget/closest-to-vivid.hs:37:1)
These potential instances exist:
instance Message format (MessageA format)
-- Defined at riddles/gadt-forget/closest-to-vivid.hs:30:10
instance Message format (MessageB format)
-- Defined at riddles/gadt-forget/closest-to-vivid.hs:32:10
• In the second argument of ‘(++)’, namely ‘theMessage msg’
In the second argument of ‘(++)’, namely
‘" now sounds like " ++ theMessage msg’
In the second argument of ‘($)’, namely
‘name ++ " now sounds like " ++ theMessage msg’
|
38 | print $ name ++ " now sounds like " ++ theMessage msg

Message is a multi-parameter typeclass. In order to determine which instance to use, there needs to be a concrete choice for a and for format. However, the method
theMessage :: a -> String
doesn't even mention format, so we have no way of figuring out which concrete type to use to find an instance of Message. The ambiguous type error you presumably got was about this (but that can be a tricky error message, I don't blame you for just enabling the extension).
The quick fix is to manually specify the format variable using ScopedTypeVariables and TypeApplications (or adding a Proxy format argument to theMessage).
play :: forall format m. Message format m => Synth format -> m -> IO ()
play (Synth name) msg =
print $ name ++ " now sounds like " ++ theMessage #format msg
However, the Message class raises a red flag as a misuse of typeclasses. It's not always bad, but whenever you see a class whose methods all have types like
:: a -> Foo
:: a -> Bar
i.e. they take a single a in contravariant position, it's likely that you don't need a typeclass at all. It's often cleaner to transform the class into a data type, like so:
data Message format = Message { theMessage :: String }
wherein each method becomes a record field. Then concrete types that you instantiated, such as your MessageA, get "demoted" to functions:
messageA :: String -> Message format
messageA msg = Message { theMessage = msg }
Whenever you would have passed an a with a Message constraint, just pass a Message instead. a dissolves into nothingness.
After you do this factoring you might be noticing that a lot of what you have written is sort of tautological and unnecessary. Good! Remove it!

When type checking code involving polymorphic bindings, the type inference engine creates fresh type variables for each use of the binding.
Here's a concrete example:
show () ++ show True
Now, we know that show :: Show a => a -> String. Above the first call to show chooses a ~ (), the second one chooses a ~ Bool. Wait! That looks as a contradiction since () and Bool are distinct types, so they can not be both equal to a. Is that it?
Nah, it is not a contradiction... it looks clear that each call of show can make its choice of a independently. During type inference this is done, roughly, as follows.
For each call we generate a fresh type variable, by renaming universally quantified type variables in the polymorphic type at hand
-- for the first call
show :: Show a0 => a0 -> String
-- for the second call
show :: Show a1 => a1 -> String
Then, we simply pick a0 ~ () and a1 ~ Bool and we are done. The user never realized that this was going on under the hood.
In case there is a type error, however, the freshly generated variables can be reported to the user, revealing a piece of the underlying inference algorithm. For instance
show []
Here, two polymorphic values are used, so we generate fresh variables for both.
[] :: [a0]
show :: Show a1 => a1 -> String
To typecheck, we need a1 ~ [a0], so we end up with (after some context reduction, which does not matter now):
[] :: [a0]
show :: Show a0 => [a0] -> String
Good, we no longer have a1 around. But what about a0? We do not have found any specific value for a0. Indeed, we can not do that, since the code does not contain anything to force that choice: a0 remains an ambiguous type at the end.
This happens because [] can create a list of any type, while show can take a list of any type as input (as long as its element type is showable). But these constraints do not tell us what the type should be!
Concluding, the code is ambiguous, so we have to fix it by telling GHC what type we choose. Any of these would be fine
show ([] :: [Int]) -- choose a0 ~ Int
show ([] :: [Bool]) -- choose a0 ~ Bool
show ([] :: [Char]) -- choose a0 ~ Char
In your code
play :: Message format m => Synth format -> m -> IO ()
play (Synth name) msg =
print $ name ++ " now sounds like " ++ theMessage msg
there is nothing which forces theMessage msg to use the same format which appears in the type of play. It is perhaps "obvious" to you that it should be, but it is not the only possible choice.
Choosing the same format is tricky here since your class has ambiguous types. This could still be used by turning on TypeApplciations and AmbiguousTypes, but something tells me that your design might be wrong, so I am a bit cautious here to suggest a solution. What you are trying to achieve? Why does the type of the Message not mention format in any way?

Related

Result type of a polyvariadic function in haskell

While studying polyvariadic functions in Haskell I stumbled across the following SO questions:
How to create a polyvariadic haskell function?
Haskell, polyvariadic function and type inference
and thought I will give it a try by implementing a function which takes a variable number of strings and concatenates/merges them into a single string:
{-# LANGUAGE FlexibleInstances #-}
class MergeStrings r where
merge :: String -> r
instance MergeStrings String where
merge = id
instance (MergeStrings r) => MergeStrings (String -> r) where
merge acc = merge . (acc ++)
This works so far if I call merge with at least one string argument and if I provide the final type.
foo :: String
foo = merge "a" "b" "c"
Omitting the final type results in an error, i.e., compiling the following
bar = merge "a" "b" "c"
results in
test.hs:12:7: error:
• Ambiguous type variable ‘t0’ arising from a use of ‘merge’
prevents the constraint ‘(MergeStrings t0)’ from being solved.
Relevant bindings include bar :: t0 (bound at test.hs:12:1)
Probable fix: use a type annotation to specify what ‘t0’ should be.
These potential instances exist:
instance MergeStrings r => MergeStrings (String -> r)
-- Defined at test.hs:6:10
instance MergeStrings String -- Defined at test.hs:4:10
• In the expression: merge "a" "b" "c"
In an equation for ‘bar’: bar = merge "a" "b" "c"
|
12 | bar = merge "a" "b" "c"
|
The error message makes perfect sense since I could easily come up with, for example
bar :: String -> String
bar = merge "a" "b" "c"
baz = bar "d"
rendering bar not into a single string but into a function which takes and returns one string.
Is there a way to tell Haskell that the result type must be of type String? For example, Text.Printf.printf "hello world" evaluates to type String without explicitly defining.
printf works without type annotation because of type defaulting in GHCi. The same mechanism that allows you to eval show $ 1 + 2 without specifying concrete types.
GHCi tries to evaluate expressions of type IO a, so you just need to add appropriate instance for MergeStrings:
instance (a ~ ()) => MergeStrings (IO a) where
merge = putStrLn
Brad (in a comment) and Max are not wrong saying that the defaulting of printf "…" … to IO ( ) is the reason for it working in ghci without type annotations. But it is not the end of the story. There are things we can do to make your definition of bar work.
First, I should mention the «monomorphism restriction» — an obscure and unintuitive type inference rule we have in Haskell. For whatever reason, the designers of Haskell decided that a top level definition without a type signature should have no polymorphic variables in its inferred type — that is, be monomorphic. bar is polymorphic, so you can see that it would be affected.
Some type classes (particularly numbers) have defaulting rules that allow you to say x = 13 without a type signature and have it inferred that x :: Integer — or whatever other type you set as default. Type defaulting is only available for a few blessed classes, so you cannot have it for your own class, and without a designated default GHC cannot decide what particular monomorphic type to choose.
But you can do other things, beside defaulting, to make the type checker happy — either:
Disable the monomorphism restriction.
Assign an explicit polymorphic type signature: bar :: MergeStrings r => r
Now bar is polymorphic and works as you would expect. See:
λ putStrLn bar
abc
λ putStrLn (bar "x")
abcx
λ putStrLn (bar "x" "y")
abcxy
You can also use defaulting to make expressions such as show bar work. Since Show is among the classes that you can default when extended default rules are enabled, you can issue default (String) in the module where you want to use show bar and it will work as you would expect.

When do I need type annotations?

Consider these functions
{-# LANGUAGE TypeFamilies #-}
tryMe :: Maybe Int -> Int -> Int
tryMe (Just a) b = a
tryMe Nothing b = b
class Test a where
type TT a
doIt :: TT a -> a -> a
instance Test Int where
type TT Int = Maybe Int
doIt (Just a) b = a
doIt (Nothing) b = b
This works
main = putStrLn $ show $ tryMe (Just 2) 25
This doesn't
main = putStrLn $ show $ doIt (Just 2) 25
{-
• Couldn't match expected type ‘TT a0’ with actual type ‘Maybe a1’
The type variables ‘a0’, ‘a1’ are ambiguous
-}
But then, if I specify the type for the second argument it does work
main = putStrLn $ show $ doIt (Just 2) 25::Int
The type signature for both functions seem to be the same. Why do I need to annotate the second parameter for the type class function? Also, if I annotate only the first parameter to Maybe Int it still doesn't work. Why?
When do I need to cast types in Haskell?
Only in very obscure, pseudo-dependently-typed settings where the compiler can't proove that two types are equal but you know they are; in this case you can unsafeCoerce them. (Which is like C++' reinterpret_cast, i.e. it completely circumvents the type system and just treats a memory location as if it contains the type you've told it. This is very unsafe indeed!)
However, that's not what you're talking about here at all. Adding a local signature like ::Int does not perform any cast, it merely adds a hint to the type checker. That such a hint is needed shouldn't be surprising: you didn't specify anywhere what a is supposed to be; show is polymorphic in its input and doIt polymorphic in its output. But the compiler must know what it is before it can resolve the associated TT; choosing the wrong a might lead to completely different behaviour from the intended.
The more surprising thing is, really, that sometimes you can omit such signatures. The reason this is possible is that Haskell, and more so GHCi, has defaulting rules. When you write e.g. show 3, you again have an ambiguous a type variable, but GHC recognises that the Num constraint can be “naturally” fulfilled by the Integer type, so it just takes that pick.
Defaulting rules are handy when quickly evaluating something at the REPL, but they are fiddly to rely on, hence I recommend you never do it in a proper program.
Now, that doesn't mean you should always add :: Int signatures to any subexpression. It does mean that, as a rule, you should aim for making function arguments always less polymorphic than the results. What I mean by that: any local type variables should, if possible, be deducable from the environment. Then it's sufficient to specify the type of the final end result.
Unfortunately, show violates that condition, because its argument is polymorphic with a variable a that doesn't appear in the result at all. So this is one of the functions where you don't get around having some signature.
All this discussion is fine, but it hasn't yet been stated explicitly that in Haskell numeric literals are polymorphic. You probably knew that, but may not have realized that it has bearing on this question. In the expression
doIt (Just 2) 25
25 does not have type Int, it has type Num a => a — that is, its type is just some numeric type, awaiting extra information to pin it down exactly. And what makes this tricky is that the specific choice might affect the type of the first argument. Thus amalloy's comment
GHC is worried that someone might define an instance Test Integer, in which case the choice of instance will be ambiguous.
When you give that information — which can come from either the argument or the result type (because of the a -> a part of doIt's signature) — by writing either of
doIt (Just 2) (25 :: Int)
doIt (Just 2) 25 :: Int -- N.B. this annotates the type of the whole expression
then the specific instance is known.
Note that you do not need type families to produce this behavior. This is par for the course in typeclass resolution. The following code will produce the same error for the same reason.
class Foo a where
foo :: a -> a
main = print $ foo 42
You might be wondering why this doesn't happen with something like
main = print 42
which is a good question, that leftroundabout has already addressed. It has to do with Haskell's defaulting rules, which are so specialized that I consider them little more than a hack.
With this expression:
putStrLn $ show $ tryMe (Just 2) 25
We've got this starting information to work from:
putStrLn :: String -> IO ()
show :: Show a => a -> String
tryMe :: Maybe Int -> Int -> Int
Just :: b -> Maybe b
2 :: Num c => c
25 :: Num d => d
(where I've used different type variables everywhere, so we can more easily consider them all at once in the same scope)
The job of the type-checker is basically to find types to choose for all of those variables, so and then make sure that the argument and result types line up, and that all the required type class instances exist.
Here we can see that tryMe applied to two arguments is going to be an Int, so a (used as input to show) must be Int. That requires that there is a Show Int instance; indeed there is, so we're done with a.
Similarly tryMe wants a Maybe Int where we have the result of applying Just. So b must be Int, and our use of Just is Int -> Maybe Int.
Just was applied to 2 :: Num c => c. We've decided it must be applied to an Int, so c must be Int. We can do that if we have Num Int, and we do, so c is dealt with.
That leaves 25 :: Num d => d. It's used as the second argument to tryMe, which is expecting an Int, so d must be Int (again discharging the Num constraint).
Then we just have to make sure all the argument and result types line up, which is pretty obvious. This is mostly rehashing the above since we made them line up by choosing the only possible value of the type variables, so I won't get into it in detail.
Now, what's different about this?
putStrLn $ show $ doIt (Just 2) 25
Well, lets look at all the pieces again:
putStrLn :: String -> IO ()
show :: Show a => a -> String
doIt :: Test t => TT t -> t -> t
Just :: b -> Maybe b
2 :: Num c => c
25 :: Num d => d
The input to show is the result of applying doIt to two arguments, so it is t. So we know that a and t are the same type, which means we need Show t, but we don't know what t is yet so we'll have to come back to that.
The result of applying Just is used where we want TT t. So we know that Maybe b must be TT t, and therefore Just :: _b -> TT t. I've written _b using GHC's partial type signature syntax, because this _b is not like the b we had before. When we had Just :: b -> Maybe b we could pick any type we liked for b and Just could have that type. But now we need some specific but unknown type _b such that TT t is Maybe _b. We don't have enough information to know what that type is yet, because without knowing t we don't know which instance's definition of TT t we're using.
The argument of Just is 2 :: Num c => c. So we can tell that c must also be _b, and this also means we're going to need a Num _b instance. But since we don't know what _b is yet we can't check whether there's a Num instance for it. We'll come back to it later.
And finally the 25 :: Num d => d is used where doIt wants a t. Okay, so d is also t, and we need a Num t instance. Again, we still don't know what t is, so we can't check this.
So all up, we've figured out this:
putStrLn :: String -> IO ()
show :: t -> String
doIt :: TT t -> t -> t
Just :: _b -> TT t
2 :: _b
25 :: t
And have also these constraints waiting to be solved:
Test t, Num t, Num _b, Show t, (Maybe _b) ~ (TT t)
(If you haven't seen it before, ~ is how we write a constraint that two type expressions must be the same thing)
And we're stuck. There's nothing further we can figure out here, so GHC is going to report a type error. The particular error message you quoted is complaining that we can't tell that TT t and Maybe _b are the same (it calls the type variables a0 and a1), since we didn't have enough information to select concrete types for them (they are ambiguous).
If we add some extra type signatures for parts of the expression, we can go further. Adding 25 :: Int1 immediately lets us read off that t is Int. Now we can get somewhere! Lets patch that into the constrints we had yet to solve:
Test Int, Num Int, Num _b, Show Int, (Maybe _b) ~ (TT Int)
Num Int and Show Int are obvious and built in. We've got Test Int too, and that gives us the definition TT Int = Maybe Int. So (Maybe _b) ~ (Maybe Int), and therefore _b is Int too, which also allows us to discharge that Num _b constraint (it's Num Int again). And again, it's easy now to verify all the argument and result types match up, since we've filled in all the type variables to concrete types.
But why didn't your other attempt work? Lets go back to as far as we could get with no additional type annotation:
putStrLn :: String -> IO ()
show :: t -> String
doIt :: TT t -> t -> t
Just :: _b -> TT t
2 :: _b
25 :: t
Also needing to solve these constraints:
Test t, Num t, Num _b, Show t, (Maybe _b) ~ (TT t)
Then add Just 2 :: Maybe Int. Since we know that's also Maybe _b and also TT t, this tells us that _b is Int. We also now know we're looking for a Test instance that gives us TT t = Maybe Int. But that doesn't actually determine what t is! It's possible that there could also be:
instance Test Double where
type TT Double = Maybe Int
doIt (Just a) _ = fromIntegral a
doIt Nothing b = b
Now it would be valid to choose t as either Int or Double; either would work fine with your code (since the 25 could also be a Double), but would print different things!
It's tempting to complain that because there's only one instance for t where TT t = Maybe Int that we should choose that one. But the instance selection logic is defined not to guess this way. If you're in a situation where it's possible that another matching instance should exist, but isn't there due to an error in the code (forgot to import the module where it's defined, for example), then it doesn't commit to the only matching instance it can see. It only chooses an instance when it knows no other instance could possibly apply.2
So the "there's only one instance where TT t = Maybe Int" argument doesn't let GHC work backward to settle that t could be Int.
And in general with type families you can only "work forwards"; if you know the type you're applying a type family to you can tell from that what the resulting type should be, but if you know the resulting type this doesn't identify the input type(s). This is often surprising, since ordinary type constructors do let us "work backwards" this way; we used this above to conclude from Maybe _b = Maybe Int that _b = Int. This only works because with new data declarations, applying the type constructor always preserves the argument type in the resulting type (e.g. when we apply Maybe to Int, the resulting type is Maybe Int). The same logic doesn't work with type families, because there could be multiple type family instances mapping to the same type, and even when there isn't there is no requirement that there's an identifiable pattern connecting something in the resulting type to the input type (I could have type TT Char = Maybe (Int -> Double, Bool).
So you'll often find that when you need to add a type annotation, you'll often find that adding one in a place whose type is the result of a type family doesn't work, and you'll need to pin down the input to the type family instead (or something else that is required to be the same type as it).
1 Note that the line you quoted as working in your question main = putStrLn $ show $ doIt (Just 2) 25::Int does not actually work. The :: Int signature binds "as far out as possible", so you're actually claiming that the entire expression putStrLn $ show $ doIt (Just 2) 25 is of type Int, when it must be of type IO (). I'm assuming when you really checked it you put brackets around 25 :: Int, so putStrLn $ show $ doIt (Just 2) (25 :: Int).
2 There are specific rules about what GHC considers "certain knowledge" that there could not possibly be any other matching instances. I won't get into them in detail, but basically when you have instance Constraints a => SomeClass (T a), it has to be able to unambiguously pick an instance only by considering the SomeClass (T a) bit; it can't look at the constraints left of the => arrow.

Can't properly define transformation from universal type, that defined with GADT

I've defined an universal data type that can contain anything (well, with current implementation not totally anything)!
Here it is (complete code):
{-#LANGUAGE NoMonomorphismRestriction#-}
{-#LANGUAGE GADTs#-}
{-#LANGUAGE StandaloneDeriving#-}
data AnyT where
Any :: (Show a, Read a) => a -> AnyT
readAnyT :: (Read a, Show a) => (String -> a) -> String -> AnyT
readAnyT readFun str = Any $ readFun str
showAnyT :: AnyT -> String
showAnyT (Any thing) = show thing
deriving instance Show AnyT --Just for convinience!
a = [Any "Hahaha", Any 123]
And I can play with it in console:
*Main> a
[Any "Hahaha",Any 123]
it :: [AnyT]
*Main> readAnyT (read::String->Float) "134"
Any 134.0
it :: AnyT
*Main> showAnyT $ Any 125
"125"
it :: String
Well, I have it, but I need to process it somehow. For example, let's define transformation functions (functions definition, add to previous code):
toAnyT :: (Show a, Read a) => a -> AnyT -- Rather useless
toAnyT a = Any a
fromAny :: AnyT -> a
fromAny (Any thing) = thing
And there is the problem! the fromAny definition from previous code is incorrect! And I don't know how to make it correct. I get the error in GHCi:
2.hs:18:23:
Could not deduce (a ~ a1)
from the context (Show a1, Read a1)
bound by a pattern with constructor
Any :: forall a. (Show a, Read a) => a -> AnyT,
in an equation for `fromAny'
at 2.hs:18:10-18
`a' is a rigid type variable bound by
the type signature for fromAny :: AnyT -> a at 2.hs:17:12
`a1' is a rigid type variable bound by
a pattern with constructor
Any :: forall a. (Show a, Read a) => a -> AnyT,
in an equation for `fromAny'
at 2.hs:18:10
In the expression: thing
In an equation for `fromAny': fromAny (Any thing) = thing
Failed, modules loaded: none.
I tried some other ways that giving errors too.
I have rather bad solution for this: defining necessary functions via showAnyT and read (replace previous function definitions):
toAnyT :: (Show a, Read a) => a -> AnyT -- Rather useless
toAnyT a = Any a
fromAny :: Read a => AnyT -> a
fromAny thing = read (showAnyT thing)
Yes, it's work. I can play with it:
*Main> fromAny $ Any 1352 ::Float
1352.0
it :: Float
*Main> fromAny $ Any 1352 ::Int
1352
it :: Int
*Main> fromAny $ Any "Haha" ::String
"Haha"
it :: String
But I think it's bad, because it uses string to transform.
Could you please help me to find neat and good solution?
First a disclaimer: I don't know the whole context of the problem you are trying to solve, but the first impression I get is that this kind of use of existentials is the wrong tool for the job and you might be trying to implement some code pattern that is common in object-oriented languaged but a poor fit for Haskell.
That said, existential types like the one you have here are usually like black holes where once you put something in, the type information is lost forever and you can't cast the value back to its original type. However, you can operate on existential values via typeclasses (as you've done with Show and Read) so you can use the typeclass Typeable to retain the original type information:
import Data.Typeable
data AnyT where
Any :: (Show a, Read a, Typeable a) => a -> AnyT
Now you can implement all the functions you have, as long as you add the new constraint to them as well:
readAnyT :: (Read a, Show a, Typeable a) => (String -> a) -> String -> AnyT
readAnyT readFun str = Any $ readFun str
showAnyT :: AnyT -> String
showAnyT (Any thing) = show thing
toAnyT :: (Show a, Read a, Typeable a) => a -> AnyT -- Rather useless
toAnyT a = Any a
fromAny can be implemented as returning a Maybe a (since you cannot be sure if the value you are getting out is of the type you are expecting).
fromAny :: Typeable a => AnyT -> Maybe a
fromAny (Any thing) = cast thing
You're using GADTs to create an existential data type. The type a in the constructor existed, but there's no way to recover it. The only information available to you is that it has Show and Read instances. The exact type is forgotten, because that's what your constructor's type instructs the type system to do. "Make sure this type has the proper instances, then forget what it is."
There is one function you've missed, by the way:
readLike :: String -> AnyT -> AnyT
readLike s (Any a) = Any $ read s `asTypeOf` a
Within the context of the pattern match, the compiler knows that whatever type a has, there is a Read instance, and it can apply that instance. Even though it's not sure what type a is. But all it can do with it is either show it, or read strings as the same type as it.
What you have is something called Existential type. If you follow that link than you will find that in this pattern the only way to work with the "data" inside the container type is to use type classes.
In your current example you mentioned that a should have Read and Show instances and that means only the functions in these type classes can be used on a and nothing else and if you want to support some more operations on a then it should be constrained with the required type class.
Think it like this: You can put anything in a box. Now when you extract something out of that box you have no way to specify what you will get out of it as you can put anything inside it. Now if you say that you can put any eatable inside this box, then you are sure that when you pick something from this box it will be eatable.

"enable_if" in Haskell

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.

Can Either be used for a kind of simple polymorphism?

I tried writing a simple function that takes an Either type (possibly parameterized by two different types) and does one thing if it gets Left and another thing if it gets Right. the following code,
someFunc :: (Show a, Show b) => Either a b -> IO ()
someFunc (Left x) = print $ "Left " ++ show x
someFunc (Right x) = print $ "Right " ++ show x
main = do
someFunc (Left "Test1")
someFunc (Right "Test2")
However, this gives,
Ambiguous type variable `b0' in the constraint:
(Show b0) arising from a use of `someFunc'
Probable fix: add a type signature that fixes these type variable(s)
In a stmt of a 'do' expression: someFunc (Left "Test1")
and
Ambiguous type variable `a0' in the constraint:
(Show a0) arising from a use of `someFunc'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: someFunc (Right "Test2")
If I understand correctly, when I call the function with Left x, it is complaining because it doesn't know the type of the Right x variant, and vice-versa. However, this branch of the function is not used. Is there a better way to do this?
You can make this work by explicitly specifying the other type:
main = do
someFunc (Left "Test1" :: Either String ())
someFunc (Right "Test2" :: Either () String)
but I agree with x13n that this probably isn't the best way to do whatever you're trying to do. Note that someFunc is functionally identical to
someFunc :: (Show a) => Bool -> a -> IO ()
someFunc False x = print $ "Left " ++ show x
someFunc True x = print $ "Right " ++ show x
because the only information you derive from the structure of the Either is whether it's a Left or Right. This version also doesn't require you to specify a placeholder type when you use it.
This is a good question, because it made me think about why Haskell behaves this way.
class PseudoArbitrary a where
arb :: a
instance PseudoArbitrary Int where
arb = 4
instance PseudoArbitrary Char where
arb = 'd'
instance PseudoArbitrary Bool where
arb = True
reallyDumbFunc :: (PseudoArbitrary a, PseudoArbitrary b) =>
Either a b -> Either a b
reallyDumbFunc (Left x) = Right arb
reallyDumbFunc (Right x) = Left arb
So check this out. I've made a typeclass PseudoArbitrary, where instances of the typeclass provide a (pseudo-)arbitrary element of their type. Now I have a reallyDumbFunction that takes an Either a b, where both a and b have PseudoArbitrary instances, and if a Left was put in, I produce a Right, with a (pseudo-)arbitrary value of type b in it, and vice versa. So now let's play in ghci:
ghci> reallyDumbFunc (Left 'z')
Ambiguous type variable blah blah blah
ghci> reallyDumbFunc (Left 'z' :: Either Char Char)
Right 'd'
ghci> reallyDumbFunc (Left 'z' :: Either Char Int)
Right 4
Whoa! Even though all I changed was the type of the input, it totally changed the type and value of the output! This is why Haskell cannot resolve the ambiguity by itself: because that would require analyzing your function in complicated ways to make sure you are not doing things like reallyDumbFunc.
Well, that depends heavily on what you are trying to do, doesn't it? As you already found out, in order to use Left constructor, you need to know the type it constructs. And full type requires information on both a and b.
Better way to achieve polymorphism in Haskell is to use type classes. You can easily provide different implementations of "methods" for different instances.
Good comparison of both object-orientation and type classes concepts can be found here.

Resources