2015-01-08 22 views
3

我有一個巧妙的類型級別的機制,可以在GHC 7.6上工作,但不是更高的版本。回首我不完全知道爲什麼它沒有計算過,但無論如何,我想找回這個功能莫名其妙:GHC 7.6下工作的代碼的歧義檢查和寬泛的覆蓋條件失敗

{-# 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 @[email protected] with polymorphic arguments, yielding @[email protected] 
    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 

這依賴於tagged庫上GHC 7.6。我們可以用它喜歡:

$ 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 

然而,這並不編譯至少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 

我覺得answer here是相關的,但我還不知道這個建議。

有可能我可以解決這個問題。我使用這個類的唯一地方是在形式的簽名:

instance (Foo tab, Applied t tab)=> Bar (Proxy t) where 

這可能表明我要讓Foo種多態,但這是一個複雜的大圖書館,我不知道這是否改變將是可能的。

+2

這只是一個7.6接受了這個錯誤。請參閱[8634](https://ghc.haskell.org/trac/ghc/ticket/8634)上的討論,該論點指向[1241](https://ghc.haskell.org/trac/ghc/ticket/ 1241),(2247)(https://ghc.haskell.org/trac/ghc/ticket/2247)和[8356](https://ghc.haskell.org/trac/ghc/ticket/8356)進一步澄清。要說出你可以做什麼,我們可能需要更多地瞭解你想要達到的目標。 –

+1

如果我理解正確,你想斷言某些't :: *^n - > *'有一個實例'Foo(t a_1 a_2 .. a_n)',其中'a_i'是不同類型的變量。如果是這種情況,你可以用'Applied(t X)tab'替換'Applied(t a)tab',其中X是任何類型。只要X在你的模塊中被定義並且沒有被導出,沒有人能夠真正地使用這個類型創建一個實例,所以任何與'X'統一的實例必須被賦予一個類型變量。 – user2407038

回答

1

如果我擺脫了FD,並啓用-XAllowAmbiguousTypes,您的ghci示例適用於ghc-7.8.3中的我。該擴展需要您在instance (Foo tab, Applied t tab)=> Bar (Proxy t)中使用applied函數的註釋(使用ScopedTypeVariables)。