understanding type classes and class constraints

Hi everyone, I'm currently enjoying to learn Haskell and came upon a problem I don't understand: Motivated by the Learn you a Haskell / yes-no typeclass example I tried to create a simple "Tester" type class: class Tester a where test :: a -> Bool I wasn't to define the rules when test returns True/False for various types, e.g. instance Tester Integer where test 0 = False test _ = True For the Maybe instance I want to delegate to the value of Just and add a class constraint: instance (Tester m) => Tester (Maybe m) where test Nothing = False test (Just x) = test x It compiles nicely and works for Just values test (Just 3) -- True test (Just 0) -- False But test Nothing gives me No instance for (Tester a0) arising from a use of `test' The type variable `a0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance Tester m => Tester (Maybe m) instance Tester Integer In the expression: test Nothing Could you please enlighten me what's going on and how to fix my code? Thank you! Robert

When you run "test Nothing", ghc doesn't know what type Nothing is. Just 0,
ghc can deduce is a Maybe Integer. Nothing can be Maybe Integer, Maybe
(Maybe Integer), Maybe Char, etc.
Try running:
test (Nothing :: Maybe Integer)
On Sun, Nov 17, 2013 at 4:47 PM, Robert Krahn
Hi everyone,
I'm currently enjoying to learn Haskell and came upon a problem I don't understand:
Motivated by the Learn you a Haskell / yes-no typeclass example I tried to create a simple "Tester" type class:
class Tester a where test :: a -> Bool
I wasn't to define the rules when test returns True/False for various types, e.g.
instance Tester Integer where test 0 = False test _ = True
For the Maybe instance I want to delegate to the value of Just and add a class constraint:
instance (Tester m) => Tester (Maybe m) where test Nothing = False test (Just x) = test x
It compiles nicely and works for Just values test (Just 3) -- True test (Just 0) -- False
But test Nothing
gives me No instance for (Tester a0) arising from a use of `test' The type variable `a0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance Tester m => Tester (Maybe m) instance Tester Integer In the expression: test Nothing
Could you please enlighten me what's going on and how to fix my code?
Thank you! Robert
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

I guess I see the intuitive confusion. It shouldn't matter what type
Nothing is, it should always return False. But ghc doesn't like to give
results of a determined type (Bool) based on operations put on values of
undetermined type (Maybe a).
On Sun, Nov 17, 2013 at 4:54 PM, Dan Krol
When you run "test Nothing", ghc doesn't know what type Nothing is. Just 0, ghc can deduce is a Maybe Integer. Nothing can be Maybe Integer, Maybe (Maybe Integer), Maybe Char, etc.
Try running:
test (Nothing :: Maybe Integer)
On Sun, Nov 17, 2013 at 4:47 PM, Robert Krahn
wrote: Hi everyone,
I'm currently enjoying to learn Haskell and came upon a problem I don't understand:
Motivated by the Learn you a Haskell / yes-no typeclass example I tried to create a simple "Tester" type class:
class Tester a where test :: a -> Bool
I wasn't to define the rules when test returns True/False for various types, e.g.
instance Tester Integer where test 0 = False test _ = True
For the Maybe instance I want to delegate to the value of Just and add a class constraint:
instance (Tester m) => Tester (Maybe m) where test Nothing = False test (Just x) = test x
It compiles nicely and works for Just values test (Just 3) -- True test (Just 0) -- False
But test Nothing
gives me No instance for (Tester a0) arising from a use of `test' The type variable `a0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance Tester m => Tester (Maybe m) instance Tester Integer In the expression: test Nothing
Could you please enlighten me what's going on and how to fix my code?
Thank you! Robert
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Sun, Nov 17, 2013 at 7:47 PM, Robert Krahn
instance Tester Integer where test 0 = False test _ = True
For the Maybe instance I want to delegate to the value of Just and add a class constraint:
instance (Tester m) => Tester (Maybe m) where test Nothing = False test (Just x) = test x
It compiles nicely and works for Just values test (Just 3) -- True test (Just 0) -- False
But test Nothing
gives me No instance for (Tester a0) arising from a use of `test'
Several things are happening here. First is that numbers undergo defaulting; with nothing else to specify the type of `3` or `0`, they default to Integer and all is well. This cannot be said of `Nothing`; it needs to pick an instance, but `Nothing` doesn't give it anything to work from. "But I only have an instance for Integer!" Typeclasses work under the "open world assumption": a typeclass could be added at any time, so it cannot commit to a given typeclass instance simply because it only happens to know of one valid instance. In particular, it cannot conclude that `Nothing` is of type `Maybe Integer` solely because it happens to only be aware of a `Tester Integer` instance. (Instances are program global and cannot be hidden, so not making the open world assumption could easily cause programs to completely change their meaning with the addition of a single additional instance *anywhere* in that program, even if not imported to that module.) -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Thanks a lot for the thorough and quick explanations!
On Sun, Nov 17, 2013 at 6:57 PM, Brandon Allbery
On Sun, Nov 17, 2013 at 7:47 PM, Robert Krahn
wrote: instance Tester Integer where test 0 = False test _ = True
For the Maybe instance I want to delegate to the value of Just and add a class constraint:
instance (Tester m) => Tester (Maybe m) where test Nothing = False test (Just x) = test x
It compiles nicely and works for Just values test (Just 3) -- True test (Just 0) -- False
But test Nothing
gives me No instance for (Tester a0) arising from a use of `test'
Several things are happening here. First is that numbers undergo defaulting; with nothing else to specify the type of `3` or `0`, they default to Integer and all is well.
This cannot be said of `Nothing`; it needs to pick an instance, but `Nothing` doesn't give it anything to work from.
"But I only have an instance for Integer!" Typeclasses work under the "open world assumption": a typeclass could be added at any time, so it cannot commit to a given typeclass instance simply because it only happens to know of one valid instance. In particular, it cannot conclude that `Nothing` is of type `Maybe Integer` solely because it happens to only be aware of a `Tester Integer` instance.
(Instances are program global and cannot be hidden, so not making the open world assumption could easily cause programs to completely change their meaning with the addition of a single additional instance *anywhere* in that program, even if not imported to that module.)
-- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (3)
-
Brandon Allbery
-
Dan Krol
-
Robert Krahn