2013-05-30 69 views
1

以下是我沒有嘗試提取bTypeRef的TypeRef:獲取函數結果類型

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 

有什麼不對?如何解決這個問題?

+4

查找到'ScopedTypeVariables' – luqui

+0

@luqui你快) –

回答

2

的問題是這種類型的變量沒有標準哈斯克爾範圍的,所以在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

你能更多地討論爲什麼'FORALL A B。 '部分有所作爲? –

+1

@NikitaVolkov它是擴展的一部分。 「具有明確量化的聲明類型簽名(使用forall)在已命名函數的定義中引入了明確量化的類型變量。」 –

+1

@NikitaVolkov:無論如何,這些將被編譯器隱式添加。有了這個擴展,它們只是用來標記類型變量作用域的附加目的,因爲你可能不希望它們總是被作用域。 – hammar

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 .部分,使之差,和其他可能的解決方案。