[Haskell-cafe] Re: checking types with type families
Claus Reinke
claus.reinke at talk21.com
Sat Jul 3 04:23:29 EDT 2010
> Prelude> :t id :: Eq b => b -> b
> id :: Eq b => b -> b :: (Eq b) => b -> b
> Prelude> id :: Eq b => b -> b
>
> <interactive>:1:0:
> No instance for (Show (b -> b))
> arising from a use of `print' at <interactive>:1:0-19
> Possible fix: add an instance declaration for (Show (b -> b))
> In a stmt of a 'do' expression: print it
>
> The Eq constraint is irrelevant to the fact that there is no b -> b Show
> instance. The search for an instance looks only at the type part, and if
> it
> finds a suitable match, then checks if the necessary constraints are also
> in
> place.
Thanks - that first sentence is right, but not because of the second!-)
I thought the error message was misleading, speaking of instance
when it should have been speaking about instance *head*. But I
was really confused by the difference between (making the show
explicit and using scoped type variables):
*Main> :t (show (id::a->a))::forall a.Eq a=>String
<interactive>:1:0:
Ambiguous constraint `Eq a'
At least one of the forall'd type variables mentioned by the
constraint
must be reachable from the type after the '=>'
In an expression type signature: forall a. (Eq a) => String
In the expression:
(show (id :: a -> a)) :: forall a. (Eq a) => String
<interactive>:1:1:
Could not deduce (Show (a -> a)) from the context (Eq a)
arising from a use of `show' at <interactive>:1:1-15
Possible fix:
add (Show (a -> a)) to the context of an expression type signature
or add an instance declaration for (Show (a -> a))
In the expression:
(show (id :: a -> a)) :: forall a. (Eq a) => String
which does list a non-empty context from which 'Show (a->a)'
could not be deduced and
*Main> :t show (id :: Eq a => a-> a)
<interactive>:1:0:
No instance for (Show (a -> a))
arising from a use of `show' at <interactive>:1:0-25
Possible fix: add an instance declaration for (Show (a -> a))
In the expression: show (id :: (Eq a) => a -> a)
which only talks about general 'Show (a->a)' instances. We
cannot define 'instance Show (forall a. Eq a=>a->a)', which
is why the 'Eq a' constraint plays no role, I think..
Btw, the issues in the other example can be made more
explicit by defining:
class MyEq a b | a->b, b->a
instance MyEq a a
First, both FDs and TFs simplify this:
*Main> :t id :: (forall b. MyEq b Bool => b->b)
id :: (forall b. MyEq b Bool => b->b) :: Bool -> Bool
*Main> :t id :: (forall b. b~Bool => b->b)
id :: (forall b. b~Bool => b->b) :: Bool -> Bool
but the FD version here typechecks (note, though, that the
type is only partially simplified)
*Main> :t id :: (forall b. MyEq b Bool => b->b)
-> (forall b. MyEq b Bool => b->b)
id :: (forall b. MyEq b Bool => b->b)
-> (forall b. MyEq b Bool => b->b)
:: (forall b. (MyEq b Bool) => b -> b) -> Bool -> Bool
while the TF version doesn't
*Main> :t id :: (forall b. b~Bool => b->b)
-> (forall b. b~Bool => b->b)
<interactive>:1:0:
Couldn't match expected type `forall b. (b ~ Bool) => b -> b'
against inferred type `forall b. (b ~ Bool) => b -> b'
Expected type: forall b. (b ~ Bool) => b -> b
Inferred type: forall b. (b ~ Bool) => b -> b
In the expression:
id ::
(forall b. (b ~ Bool) => b -> b)
-> (forall b. (b ~ Bool) => b -> b)
Claus
More information about the Haskell-Cafe
mailing list