[英]ambiguity check and liberal coverage condition failures for code working under GHC 7.6
I had a clever bit of type-level machinery that worked on GHC 7.6 but not later versions. 我有一个聪明的类型级机械,适用于GHC 7.6但不是更高版本。 Looking back I'm not totally sure why it ever worked, but regardless I would like to get back this functionality somehow:
回想起来,我不完全确定它为什么会工作,但无论如何我想以某种方式取回这个功能:
{-# LANGUAGE
PolyKinds
, FunctionalDependencies , FlexibleInstances , FlexibleContexts
, OverlappingInstances
, ScopedTypeVariables
, TypeFamilies
, UndecidableInstances
#-}
module M where
import Data.Proxy
-- | A relation between a (maybe-partially-applied) type and that type fully
-- applied.
class Applied t (tab :: *) | t -> tab where
-- | Fully apply a type @t@ with polymorphic arguments, yielding @tab@.
applied :: Proxy t -> Proxy tab
instance Applied (t a) tab=> Applied t tab where
applied _ = applied (Proxy :: Proxy (t a))
instance t ~ tab=> Applied t tab where -- always matches when `t` is kind `*`
applied _ = Proxy :: Proxy tab
This depends on the tagged
library on GHC 7.6. 这取决于GHC 7.6上的
tagged
库。 We can use it like: 我们可以使用它:
$ ghci-7.6.3
Prelude> :l M.hs
[1 of 1] Compiling M ( M.hs, interpreted )
Ok, modules loaded: M.
*M>
*M> :t applied (Proxy :: Proxy Either)
applied (Proxy :: Proxy Either) :: Proxy (Either a a1)
*M> (return $ Right 'a') == applied (Proxy :: Proxy Either)
True
However this doesn't compile on at least GHC 7.8.3 or later: 但是,这至少不能在GHC 7.8.3或更高版本上编译:
$ ghci-7.8.3
GHCi, version 7.8.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :l M.hs
[1 of 1] Compiling M ( M.hs, interpreted )
M.hs:19:10:
Could not deduce (Applied (t a0) tab)
arising from the ambiguity check for an instance declaration
from the context (Applied (t a) tab)
bound by an instance declaration:
Applied (t a) tab => Applied t tab
at M.hs:19:10-42
The type variable ‘a0’ is ambiguous
In the ambiguity check for:
forall (k :: BOX) (k1 :: BOX) (t :: k1 -> k) tab (a :: k1).
Applied (t a) tab =>
Applied t tab
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the instance declaration for ‘Applied t tab’
M.hs:19:10:
Illegal instance declaration for ‘Applied t tab’
The liberal coverage condition fails in class ‘Applied’
for functional dependency: ‘t -> tab’
Reason: lhs type ‘t’ does not determine rhs type ‘tab’
In the instance declaration for ‘Applied t tab’
Failed, modules load
I think the answer here is related, but I don't yet understand the suggestion. 我认为这里的答案是相关的,但我还不明白这个建议。
It's possible I might be able to work around this. 我可能能够解决这个问题。 The only place I use this class is in a signature of the form:
我使用这个类的唯一地方是形式的签名:
instance (Foo tab, Applied t tab)=> Bar (Proxy t) where
Which might indicate I want to make Foo
kind-polymorphic, but this is in a big complicated library and I don't know if that change would be possible. 这可能表明我想让
Foo
变为多态,但这是一个大型复杂的库,我不知道这种改变是否可行。
Your ghci example works for me in ghc-7.8.3 if I get rid of the FD, and enable -XAllowAmbiguousTypes
. 如果我摆脱FD,你的ghci示例在ghc-7.8.3中适用于我,并启用
-XAllowAmbiguousTypes
。 That extension will require you to annotate (using ScopedTypeVariables
) the type of that applied
function when it is used in instance (Foo tab, Applied t tab)=> Bar (Proxy t)
. 该扩展将要求您在
instance (Foo tab, Applied t tab)=> Bar (Proxy t)
使用该applied
函数的类型时使用ScopedTypeVariables
进行注释( instance (Foo tab, Applied t tab)=> Bar (Proxy t)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.