Reputation: 43310
Following is my failing attempt to extract a TypeRef
of b
:
import Data.Typeable
f :: Typeable b => a -> b
f = impl
where
bTypeRep = typeOf $ (undefined :: Typeable b => (a -> b) -> b) impl
impl = undefined
The error message is following:
Could not deduce (Typeable a0) arising from a use of `typeOf'
from the context (Typeable b)
bound by the type signature for f :: Typeable b => a -> b
at src/Xet.hs:14:6-25
The type variable `a0' is ambiguous
What is wrong? How to solve this?
Upvotes: 1
Views: 127
Reputation: 139840
The problem is that type variables are not scoped in standard Haskell, so there is no connection between the type variables in the signature of f
and those in your type annotation. You might as well have written
bTypeRep = typeOf $ (undefined :: Typeable d => (c -> d) -> d) impl
The solution, as luqui suggested in the comments, is to enable the ScopedTypeVariables
extension. Note that this doesn't make all type variables scoped; you have to use explicit forall
quantifiers to indicate to the compiler when you want type variables to be scoped.
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Typeable
f :: forall a b. Typeable b => a -> b
f = impl
where
bTypeRep = typeOf $ (undefined :: Typeable b => (a -> b) -> b) impl
impl = undefined
Upvotes: 2
Reputation: 43310
The following has solved the issue. Thanks to luqui.
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Typeable
f :: forall a b . Typeable b => a -> b
f = undefined
where
bTypeRep = typeOf $ (undefined :: b)
I'm willing to accept another answer explaining, why the forall a b .
part makes the difference, and possibly other solutions.
Upvotes: 0