2015-01-08 5 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 

이 GHC 7.6에 tagged 라이브러리에 따라 달라집니다. 나는 answer here이 관련되어 생각

$ 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 

,하지만 난 아직 이해하지 않는다 그러나이 나중에 적어도 GHC 7.8.3 또는에 컴파일되지 않습니다

$ 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 

을 : 우리는 같은 사용할 수 있습니다 제안.

이 문제를 해결할 수 있습니다. 나는이 클래스를 사용하는 유일한 장소는 형식의 서명에 : 나는 Foo 종류의 다형 만들고 싶어 표시하지만,이 큰 복잡한 라이브러리에 내가 그 경우 모르는 수

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

변화가 가능할 것이다.

+2

그것은 7.6에서 이것을 받아 들였을뿐입니다. [1241] (https://ghc.haskell.org/trac/ghc/ticket/)에있는 [8634] (https://ghc.haskell.org/trac/ghc/ticket/8634)의 토론을 참조하십시오. 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 '는 구별 유형 변수입니다. 이 경우 '적용 (t a) 탭'을 '적용 (t X) 탭'으로 바꿀 수 있습니다. 여기서 X는 모든 유형입니다. X가 당신의 모듈에서 정의되고 export되지 않는다면, 아무도 실제로 그 타입으로 인스턴스를 만들 수 없으므로'X'와 통합되는 모든 인스턴스는 타입 변수로 주어져야합니다. – user2407038

답변

1

ghci 예제는 FD를 없애고 ghc-7.8.3에서 나를 위해 작동하며 -XAllowAmbiguousTypes을 사용 가능하게 설정합니다. 이 확장을 사용하면 instance (Foo tab, Applied t tab)=> Bar (Proxy t)에서 사용될 때 applied 함수의 유형에 주석을 달아야합니다 (ScopedTypeVariables 사용).