To use type variables in such a definition, you need a ScopedTypeVariables language ScopedTypeVariables , but in this case you don't need a scope type variable at all, just use
rmap :: Pointed c => (a -> b) -> Runner abc rmap f = Runner point (\(x, y, z) -> (fx, y, z))
If you really want to have (point :: c) , you can do
{-
With ScopedTypeVariables you also need to explicitly use the forall syntax and declare a and b . Again, this is not necessary for this particular problem, the GHC can automatically determine which instance of Pointed use.
Even with GHC 7.8, a type signature is not even required, it can be automatically output:
> let rmap f = Runner point (\(x, y, z) -> (fx, y, z)) > :t rmap rmap :: Pointed c => (a -> b) -> Runner abc
The origin of this error is that if (point :: c) without ScopedTypeVariables , c in the function definition is different from c in the type signature. This works with specific types, such as Int , because they are already in scope, but not so with type variables.
So why does this work without having c in the function domain: GHC type inference is really smart. This will allow you to pass in the general value until you need a specific one, then all the correct instances will be used. For example, if I had something like
> data Test abc = Test { t :: c, x :: (a, b) } deriving (Eq, Show) > instance Pointed [Double] where point = [1, 2, 3] -- Requires FlexibleInstances > let test :: Pointed c => a -> b -> Test abc | test ab = Test point (a, b) > test 1 "test" :: Test Int String [Double] Test {t = [1.0,2.0,3.0], x = (1,"test")}
Although c not displayed as an argument, it is still possible for the type checker to figure out which instance to use when I specified that the return type is Test Int String [Double] . Without specifying a signature, he instead gives me an error
<interactive>:30:1: No instance for (Pointed c0) arising from a use of `it' The type variable `c0' is ambiguous Note: there is a potential instance available: instance Pointed [Double] -- Defined at <interactive>:19:10 In the first argument of `print', namely `it' In a stmt of an interactive GHCi command: print it
because he does not know which instance of Pointed use.