获取函数结果类型的TypeRef

时间:2013-05-30 17:07:47

标签: haskell reflection

以下是我未能尝试提取TypeRef b

import Data.Typeable

f :: Typeable b => a -> b
f = impl
  where
    bTypeRep = typeOf $ (undefined :: Typeable b => (a -> b) -> b) impl
    impl = undefined

错误消息如下:

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

有什么问题?怎么解决这个问题?

2 个答案:

答案 0 :(得分:2)

问题是类型变量不是标准Haskell的范围,因此f签名中的类型变量与类型注释中的类型变量之间没有关联。你可能还写过

bTypeRep = typeOf $ (undefined :: Typeable d => (c -> d) -> d) impl

luqui在评论中建议的解决方案是启用ScopedTypeVariables扩展。请注意,这不会使所有类型变量成为范围;您必须使用显式forall量词来向编译器指示何时需要对类型变量进行作用域。

{-# 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

答案 1 :(得分:0)

以下解决了这个问题。感谢 luqui

{-# LANGUAGE ScopedTypeVariables #-}

import Data.Typeable

f :: forall a b . Typeable b => a -> b
f = undefined
  where
    bTypeRep = typeOf $ (undefined :: b)

我愿意接受另一个答案,解释为什么forall a b .部分有所不同,可能还有其他解决方案。