Asa*_*din 7 haskell existential-type typeclass
我有一些这样的代码:
{-# LANGUAGE AllowAmbiguousTypes #-}
module Foo where
import Data.Proxy
class Foo x y
class Bar x y
class Baz x y
where
baz :: Proxy x -> Proxy y -> ()
instance (Foo a v, Bar b v) => Baz a b
where
baz _ _ = ()
instance Foo String String
instance Bar Int String
Run Code Online (Sandbox Code Playgroud)
现在我真的想使用那个Baz实例,所以我写:
test :: Proxy String -> Proxy Int -> ()
test = baz
Run Code Online (Sandbox Code Playgroud)
但是当然有一个模棱两可的“存在”v类型参数我还没有修复String(并且没有fundeps),所以我得到:
[typecheck] [E] /tmp/foo/src/Main.hs:20:8: error:
• Ambiguous type variable ‘v1’ arising from a use of ‘baz’
prevents the constraint ‘(Foo [Char] v1)’ from being solved.
Probable fix: use a type annotation to specify what ‘k1’,
‘v1’ should be.
These potential instance exist:
one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: baz
In an equation for ‘test’: test = baz
Run Code Online (Sandbox Code Playgroud)
但是我怎样才能真正修复那个类型变量呢?我看不到使用可见类型应用程序修复它的方法,因为例如以下内容不起作用:
[typecheck] [E] /tmp/foo/src/Main.hs:20:8: error:
• Ambiguous type variable ‘v1’ arising from a use of ‘baz’
prevents the constraint ‘(Foo [Char] v1)’ from being solved.
Probable fix: use a type annotation to specify what ‘k1’,
‘v1’ should be.
These potential instance exist:
one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: baz
In an equation for ‘test’: test = baz
Run Code Online (Sandbox Code Playgroud)
我也看不到使用显式类型注释来修复该类型参数的方法。我是否编写了一个无法实际使用的实例?
确实不可能使用那个实例。当您调用时baz,您可以提供a和b,但不能提供v。v必须由超类和实例约束的某种组合来确定,而事实并非如此。
您应该能够在各个地方修补它。尝试
instance s ~ String => Foo String s
Run Code Online (Sandbox Code Playgroud)
或者
instance s ~ String => Bar Int s
Run Code Online (Sandbox Code Playgroud)
例如。