模糊的中间结果

时间:2017-10-15 06:40:30

标签: haskell types ghc typeclass

假设我有一个类型类,两个实例和一个定义如下的函数。

class C c where
  newC :: String -> c
  showC :: c -> String

data C1 = C1 String  

instance C C1 where
  newC string = C1 string  
  showC (C1 string) = string

data C2 = C2 String  

instance C C2 where
  newC string = C2 string  
  showC (C2 string) = string


topFn :: String -> String 
topFn = showC . newC

加载后,GHC产生一个"不明确的类型"错误,

Ambiguous type variable ‘c0’ arising from a use of ‘showC’
prevents the constraint ‘(C c0)’ from being solved.
Probable fix: use a type annotation to specify what ‘c0’ should be.
These potential instances exist:
   instance C C1 -- Defined at ambigType.hs:8:10
   instance C C2 -- Defined at ambigType.hs:14:10

我理解中间值可以是C1C2,如果没有进一步的信息,GHC无法确定它应该是什么。

编写topFn的两个版本可以解决问题。

topFn1 :: String -> String 
topFn1 = showC . (newC :: String -> C1)

topFn2 :: String -> String 
topFn2 = showC . (newC :: String -> C2)

但由于这些功能基本相同,这似乎是一个丑陋的解决方案。还有更好的方法吗?

感谢。

1 个答案:

答案 0 :(得分:3)

是的,使用TypeApplicationsAllowAmbiguousTypesExplicitForallScopedTypeVariables扩展程序。然后,将topFn修改为

topFn :: forall a. C a => String -> String 
topFn = showC . newC @a

然后,您可以使用显式类型应用调用topFntopFn @C1 "calling the C1 variant"topFn @C2 "calling the C2 variant"。如果需要,您可以定义:

topFn1 = topFn @C1
topFn2 = topFn @C2
相关问题