Why can't Haskell infer Tree type? - haskell

I followed the book to define Tree data type, but show doesn't work correctly. Why?
data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show)
test = show EmptyTree
gives the error message:
No instance for (Show a0) arising from a use of ???show???
The type variable ???a0??? is ambiguous
Note: there are several potential instances:
instance Show a => Show (Tree a)
-- Defined at /Users/gzhao/Documents/workspace/hsTest2/src/Tree.hs:3:62
instance Show Double -- Defined in ???GHC.Float???
instance Show Float -- Defined in ???GHC.Float???
...plus 25 others
In the expression: show EmptyTree
In an equation for ???test???: test = show EmptyTree

The problem is that EmptyTree has type Tree a for any type a. Even though it won't actually affect the final output, the compiler wants to know which a you mean.
The simplest fix is to pick a specific type, e.g. with show (EmptyTree :: Tree ()). This uses the unit type (), which is in some sense the simplest possible type, but you can also use any other type that has a Show instance, like Int, String etc.

Related

Printer in Haskell for Subst in Data.Comp.Variables

I have a function which returns a Subst defined in this library:
http://hackage.haskell.org/package/compdata-0.1/docs/Data-Comp-Variables.html#t:Subst
I am trying to print the return value. The printer should show a mapping from variables to terms.
When I try to print the result, I get:
• No instance for (Show (Cxt NoHole CTypeF ()))
arising from a use of ‘print’
• In the expression: (print subst)
I think this means I must implement a printer. I know that when it's a user defined class, I can do 'deriving show'. Could someone point out how I should go about printing this?
Also, this is my CTypeF structure.
data CTypeF a
= CVarF Int
| CArrF a a
| CIntF
| CBoolF
deriving (Eq, Data, Functor, Foldable, Traversable, Show)
It derives show, so I don't think the issue is here.
Cxt has a Show instance, but it requires its f parameter to have an instance of ShowF.
(Functor f, ShowF f, Show a) => Show (Cxt h f a)
So you need to make CTypeF have an instance of ShowF. To do that, you can use makeShowF with Template Haskell.
$(makeShowF ''CTypeF)

Default to a typeclass when a data type does not instantiate it [duplicate]

What I'd like to achieve is that any instance of the following class (SampleSpace) should automatically be an instance of Show, because SampleSpace contains the whole interface necessary to create a String representation and hence all possible instances of the class would be virtually identical.
{-# LANGUAGE FlexibleInstances #-}
import Data.Ratio (Rational)
class SampleSpace space where
events :: Ord a => space a -> [a]
member :: Ord a => a -> space a -> Bool
probability :: Ord a => a -> space a -> Rational
instance (Ord a, Show a, SampleSpace s) => Show (s a) where
show s = showLines $ events s
where
showLines [] = ""
showLines (e:es) = show e ++ ": " ++ (show $ probability e s)
++ "\n" ++ showLines es
Since, as I found out already, while matching instance declarations GHC only looks at the head, and not at contraints, and so it believes Show (s a) is about Rational as well:
[1 of 1] Compiling Helpers.Probability ( Helpers/Probability.hs, interpreted )
Helpers/Probability.hs:21:49:
Overlapping instances for Show Rational
arising from a use of ‘show’
Matching instances:
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance (Ord a, Show a, SampleSpace s) => Show (s a)
-- Defined at Helpers/Probability.hs:17:10
In the expression: show
In the first argument of ‘(++)’, namely ‘(show $ probability e s)’
In the second argument of ‘(++)’, namely
‘(show $ probability e s) ++ "" ++ showLines es
Question: is it possible (otherwise than by enabling overlapping instances) to make any instance of a typeclass automatically an instance of another too?
tl;dr: don't do that, or, if you insist, use -XOverlappingInstances.
This is not what the Show class is there for. Show is for simply showing plain data, in a way that is actually Haskell code and can be used as such again, yielding the original value.
SampleSpace should perhaps not be a class in the first place. It seems to be basically the class of types that have something like Map a Rational associated with them. Why not just use that as a field in a plain data type?
Even if we accept the design... such a generic Show instance (or, indeed, generic instance for any single-parameter class) runs into problems when someone makes another instance for a concrete type – in the case of Show, there are of course already plenty of instances around. Then how should the compiler decide which of the two instances to use? GHC can do it, in fact: if you turn on the -XOverlappingInstances extension, it will select the more specific one (i.e. instance SampleSpace s => Show (s a) is “overridden” by any more specific instance), but really this isn't as trivial as may seem – what if somebody defined another such generic instance? Crucial to recall: Haskell type classes are always open, i.e. basically the compiler has to assume that all types could possibly in any class. Only when a specific instance is invoke will it actually need the proof for that, but it can never proove that a type isn't in some class.
What I'd recommend instead – since that Show instance doesn't merely show data, it should be made a different function. Either
showDistribution :: (SampleSpace s, Show a, Ord a) => s a -> String
or indeed
showDistribution :: (Show a, Ord a) => SampleSpace a -> String
where SampleSpace is a single concrete type, instead of a class.

Make a typeclass instance automatically an instance of another

What I'd like to achieve is that any instance of the following class (SampleSpace) should automatically be an instance of Show, because SampleSpace contains the whole interface necessary to create a String representation and hence all possible instances of the class would be virtually identical.
{-# LANGUAGE FlexibleInstances #-}
import Data.Ratio (Rational)
class SampleSpace space where
events :: Ord a => space a -> [a]
member :: Ord a => a -> space a -> Bool
probability :: Ord a => a -> space a -> Rational
instance (Ord a, Show a, SampleSpace s) => Show (s a) where
show s = showLines $ events s
where
showLines [] = ""
showLines (e:es) = show e ++ ": " ++ (show $ probability e s)
++ "\n" ++ showLines es
Since, as I found out already, while matching instance declarations GHC only looks at the head, and not at contraints, and so it believes Show (s a) is about Rational as well:
[1 of 1] Compiling Helpers.Probability ( Helpers/Probability.hs, interpreted )
Helpers/Probability.hs:21:49:
Overlapping instances for Show Rational
arising from a use of ‘show’
Matching instances:
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance (Ord a, Show a, SampleSpace s) => Show (s a)
-- Defined at Helpers/Probability.hs:17:10
In the expression: show
In the first argument of ‘(++)’, namely ‘(show $ probability e s)’
In the second argument of ‘(++)’, namely
‘(show $ probability e s) ++ "" ++ showLines es
Question: is it possible (otherwise than by enabling overlapping instances) to make any instance of a typeclass automatically an instance of another too?
tl;dr: don't do that, or, if you insist, use -XOverlappingInstances.
This is not what the Show class is there for. Show is for simply showing plain data, in a way that is actually Haskell code and can be used as such again, yielding the original value.
SampleSpace should perhaps not be a class in the first place. It seems to be basically the class of types that have something like Map a Rational associated with them. Why not just use that as a field in a plain data type?
Even if we accept the design... such a generic Show instance (or, indeed, generic instance for any single-parameter class) runs into problems when someone makes another instance for a concrete type – in the case of Show, there are of course already plenty of instances around. Then how should the compiler decide which of the two instances to use? GHC can do it, in fact: if you turn on the -XOverlappingInstances extension, it will select the more specific one (i.e. instance SampleSpace s => Show (s a) is “overridden” by any more specific instance), but really this isn't as trivial as may seem – what if somebody defined another such generic instance? Crucial to recall: Haskell type classes are always open, i.e. basically the compiler has to assume that all types could possibly in any class. Only when a specific instance is invoke will it actually need the proof for that, but it can never proove that a type isn't in some class.
What I'd recommend instead – since that Show instance doesn't merely show data, it should be made a different function. Either
showDistribution :: (SampleSpace s, Show a, Ord a) => s a -> String
or indeed
showDistribution :: (Show a, Ord a) => SampleSpace a -> String
where SampleSpace is a single concrete type, instead of a class.

How does this instance declaration result in an ambiguous case?

The following snippet
data Tree k v = ETree | Node { leftTreeOf :: Tree k v,
rightTreeOf :: Tree k v,
tKey :: k,
tVal :: v
}
instance Show s => Show (Tree s s) where
show = showTree 0
yields
Illegal instance declaration for `Show (Tree s s)'
(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 (Tree s s)'
I looked it up, and the restriction that -XFlexibleInstances lifts is in place to prevent ambiguous instances from being declared.
How does having two type variables allow an ambiguous case though?
instance Show s => Show (Tree s) where
show = showTree 0
worked fine when I only needed one type variable.
Sorry, I didn't think it through.
If anyone else is having this problem, it requires 2 different type variable to be supplied to allow 2 different Show-able types:
instance (Show sk, Show sv) => Show (Tree sk sv) where
show = showTree 0
Then any contained functions (in this case showTree), need a similar signature.

Equal class misunderstanding

I have my own data type to represent nodes and edges of a graph as follows:
data Node a = Node a deriving (Show, Eq)
data Label a = Label a deriving (Show)
data Cost = CostI Int | CostF Float deriving (Show)
data Edge label node = Edge (Label label, (Node node,Node node), Cost) deriving (Show)
Now, I create a function to check whether an edge contains 2 nodes or not as follows:
isEdge:: (Eq n) => (Edge l n) -> (Node n, Node n) -> Bool
isEdge (Edge (_, (n1,n2), _)) (n3, n4) = result
where result = (n1 == n3) && (n2 == n4)
The function works well, the problem here is if I remove (Eq n) from the function, it fails. So, why is that, even though in the declaration above I declared Node as deriving from Eq class?
data Node a = Node a deriving (Show, Eq)
The Eq instance GHC derives for Node a is something like this:
instance Eq a => Eq (Node a) where
(Node x) == (Node y) = x == y
(Node x) /= (Node y) = x /= y
You can view the generated code by compiling with -ddump-deriv. The Eq a constraint is needed for obvious reasons. So, GHC couldn't infer an instance of Eq for, say, Node (a -> b) since functions can't be compared.
However, the fact that GHC can't infer an instance of Eq for Node a for some a doesn't mean it will stop you from constructing a values of type Node a where a isn't an equality type.
If you wanted to stop people from constructing non-comparable Nodes, you could try putting a constraint like this:
data Eq a => Node a = Node a deriving (Eq, Show)
But now GHC tells us we need a compiler pragma:
Illegal datatype context (use -XDatatypeContexts): Eq a =>
OK, let's add it to the top of our file:
{-# LANGUAGE DatatypeContexts #-}
Now compile:
/tmp/foo.hs:1:41: Warning: -XDatatypeContexts is deprecated: It was widely
considered a misfeature, and has been removed from the Haskell language.
The problem is that now every function using Nodes will need an Eq class constraint, which is annoying (your functions still need the constraint!). (Also, if your user wants to create Nodes using a non-equality type but never tests them for equality, what's the problem?)
There's actually a way to get GHC to do what you want, however: Generalized Algebraic Data Types (GADTs):
{-# LANGUAGE GADTs, StandaloneDeriving #-}
data Node a where
Node :: Eq a => a -> Node a
This looks just like your original definition, except that it emphasizes the Node value constructor (the one formerly on the right hand side of the data declaration) is just a function, which you can add constraints to. Now GHC knows that only equality types can be put into Nodes, and unlike our earlier attempted solution, we can make new functions that don't need a constraint:
fromNode :: Node a -> a
fromNode (Node x) = x
We can still derive Eq and Show instances, but with a slightly different syntax:
deriving instance Eq (Node a)
deriving instance Show (Node a)
(Hence the StandaloneDeriving pragma above.)
For this to work, GHC also requires us to add a Show constraint to our GADT (if you look at the generated code again, you'll see the constraints are now gone):
data Node a where
Node :: (Eq a, Show a) => a -> Node a
And now we can take the Eq constraint off isEdge, since GHC can infer it!
(This is definitely overkill for such a simple situation -- again, if people want to construct nodes with functions inside them, why shouldn't they? However, GADTs are extremely useful in pretty similar situations when you want to enforce certain properties of your data types. See a cool example).
EDIT (from the future): you can also write
data Node a = (Eq a, Show a) => Node a
but you still need to enable GADT extensions and derive instances separately. See this thread.
When you add a deriving clause to a data declaration, the derived clause will include any necessary constraints for the type variable in scope at the declaration. In this case, deriving Eq will create essentially the following instance:
instance Eq a => Eq (Node a) where
(Node a) == (Node b) = a == b
(Node a) /= (Node b) = a /= b
Any derived Eq instance will depend upon the Eq instance of types that appear to the right of the data constructor.
This is because there's really no other way to derive an Eq instance automatically. Two values are equal if they have the same type and all their components are equal. So you need to be able to test the components for equality. In order to generically test a polymorphic component for equality, you need an Eq instance.
This is true not just for Eq, but for all the derived classes. For example this code
toStr :: Edge l n -> String
toStr = show
won't work without adding the constraint (Show l, Show n). Without that constraint, the function to show an Edge doesn't know what to call to show its internal Labels and Nodes.

Resources