2010-07-30 3 views
7

모나드 변환기 유형 생성자의 인수로 유형 동의어를 사용할 수 있습니까? 특히, 적용된 모나드 변환기의 단항 형 동의어가 있다면 다른 모나드 변환기의 기본 모나드 유형으로 사용할 수 있습니까? B a의 정의에 유형의 동의어 A 확대를 방지 할 수있는 방법이 있나요모나드 변환기에서 유형 동의어 사용

-- Using type synonym of a monad transformer in another monad transformer. 

import Control.Monad.Reader 

-- inner transformer 
type A a = ReaderT Int IO a 

-- type B a = ReaderT String A a 
{- Error: 
readert2.hs:8:0: 
    Type synonym `A' should have 1 argument, but has been given 0 
    In the type synonym declaration for `B' 
-} 

-- type B a = ReaderT String (A a) a 
{- Error: 
readert2.hs:15:27: 
    Kind mis-match 
    The second argument of `ReaderT' should have kind `* -> *', 
    but `A a' has kind `*' 
    In the type `ReaderT String (A a) a' 
    In the type synonym declaration for `B' 
-} 

type B a = ReaderT String (ReaderT Int IO) a 
{- OK -} 

main = do 
    r <- flip runReaderT 39 $ do 
      n <- ask :: A Int 
      s <- flip runReaderT "foo" $ (ask :: B String) 
      return $ n + length s 
    print r 

: 나는 아래의 예제 및 오류 메시지를 참조 타입 동의어 일류 타입의 생성자로 허용되지 않습니다 보는 것과

?

답변

12

동의어를 부분적으로 적용 할 수 없습니다. 이 특정한 경우에, 당신은 쓸 수

type A = ReaderT Int IO 
type B a = ReaderT String A a 

[또는 다른 모나드 변압기에 B를 사용하는 type B = ReaderT String A을 더 나은]

그것은 그 변화는 예를 들어, newtype은/데이터를 사용하지 않고 불가능하다 일반적이다 :

type A a = Reader a Int 

type A = ...과 등가로 표시 할 수 없습니다. 어떤 의미에서이 기능은 유형 수준 람다 \a -> Reader a Int과 동일합니다.