键入具有不明确类型的应用程序

时间:2016-09-29 14:03:22

标签: haskell ghc

我最近发现-XTypeApplications,它允许我写缩写我的代码。请考虑以下事项:

{-# LANGUAGE AllowAmbiguousTypes, DataKinds, KindSignatures, RankNTypes, 
             ScopedTypeVariables, TypeApplications #-}

import Data.Tagged
import Data.Proxy

class Foo (a :: Bool) where
  foo :: Tagged a Int

instance Foo 'True where
  foo = 3

instance Foo 'False where
  foo = 4

而不是写proxy foo (Proxy::Proxy 'True),我现在可以写untag $ foo @'True,这为我节省了很多Proxy样板。没关系,但我们可以用模糊的类型做得更好:

foo' :: forall (a :: Bool) . (Foo a) => Int
foo' = untag $ foo @a

现在我可以写foo' @'True!请注意,虽然-XTypeApplications之前的类型不明确,但我不能再指定类型a了。我认为这很好,但其他人可能不会。所以我希望引入一个包装器

wrapAmbiguous :: forall (a :: Bool) b . (Foo a) => (forall (t :: Bool) . (Foo t) => b) -> Tagged a b
wrapAmbiguous f = Tagged $ f @a

(在我的实际使用案例中更为通用,但这得到了重点),因此用户不需要-XTypeApplications。但是,当我尝试使用wrapAmbiguous之类的proxy (wrapAmbiguous foo') (Proxy::Proxy 'True)时,我会收到错误

• Could not deduce (Foo a0) arising from a use of ‘foo'’
  from the context: Foo t
    bound by a type expected by the context:
               Foo t => Int
    at Foo.hs:26:18-35
  The type variable ‘a0’ is ambiguous
  These potential instances exist:
    instance Foo 'False -- Defined at Foo.hs:12:10
    instance Foo 'True -- Defined at Foo.hs:9:10
• In the first argument of ‘wrapAmbiguous’, namely ‘foo'’
  In the first argument of ‘proxy’, namely ‘(wrapAmbiguous foo')’
  In the second argument of ‘($)’, namely
    ‘proxy (wrapAmbiguous foo') (Proxy :: Proxy True)’

在我看来,这应该是合法的,但GHC显然无法统一foo'forall (t :: Bool) (Foo t) => b的类型。有没有办法让我的包装工作?

0 个答案:

没有答案