Reify 存在实例类型参数

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)

我也看不到使用显式类型注释来修复该类型参数的方法。我是否编写了一个无法实际使用的实例?

dfe*_*uer 5

确实不可能使用那个实例。当您调用时baz,您可以提供ab,但不能提供vv必须由超类和实例约束的某种组合来确定,而事实并非如此。

您应该能够在各个地方修补它。尝试

instance s ~ String => Foo String s
Run Code Online (Sandbox Code Playgroud)

或者

instance s ~ String => Bar Int s
Run Code Online (Sandbox Code Playgroud)

例如。