Woj*_*ilo 2 haskell types overloading type-inference typeclass
让我们考虑以下示例:
data A = A{x::Int} deriving(Show)
instance Func_f (A -> String) where
f _ = "ala"
class Func_f a where
f :: a
main :: IO ()
main = do
let
a = A 5
x = f a
print 5
Run Code Online (Sandbox Code Playgroud)
用.编译 ghc -XFlexibleInstances main.hs
(我试过了-XExtendedDefaultRules,但没有任何进展)
为什么在编译时会出现错误?:
main.hs:25:21:
No instance for (Func_f (A -> t0)) arising from a use of `f'
The type variable `t0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there is a potential instance available:
instance Func_f (A -> String) -- Defined at main.hs:7:10
Possible fix: add an instance declaration for (Func_f (A -> t0))
In the expression: f a
In an equation for `x': x = f a
In the expression:
do { let a = A 5
x = f a;
print 5 }
Run Code Online (Sandbox Code Playgroud)
Func_f只有一个实例,所以Haskell应该能够知道结果x = f a.您可以通过手动提供类型来修复错误,如下所示:x = f a :: String,但这不适合我的情况,因为我正在生成Haskell代码,我希望Haskell的类型推理器能够为我完成这项工作.
Tik*_*vis 13
你正在进入开放世界的假设.基本思想是GHC总是假设您可以为代码添加更多类实例.此外,您无法控制在模块之间导出和导入实例的方式.所以依靠只有一个特定类的一个实例是行不通的,会导致奇怪的错误.
从本质上讲,没有什么能阻止你 - 或者其他任何人 - 因为写下另一个例子:
instance Func_f (A -> Int) where
f _ = 10
Run Code Online (Sandbox Code Playgroud)
然后就不可能在你的代码中弄清楚你想要哪一个.这可能会导致您的代码仅在链接到另一个模块时中断!
但是,如果您实际使用了该值,则可能会使其类型受到某些其他参数的约束,并且模糊性将消失.例如,以下工作:
main :: IO ()
main = do
let a = A 5
x = f a
putStr x
Run Code Online (Sandbox Code Playgroud)
基本上,这是其中一种情况(类似于read . show),其中由于GHC如何处理类型类实例,类型签名根本不可避免.
| 归档时间: |
|
| 查看次数: |
388 次 |
| 最近记录: |