2013-05-31 1 views
10

예를 들어, ParsecT에는 정의에 여러 유형 변수가 있습니다.haskell에서 여러 유형 변수의 순서 규칙은 무엇입니까?

newtype ParsecT s u m a 
    = ParsecT {unParser :: forall b . 
       State s u 
       -> (a -> State s u -> ParseError -> m b) 
       -> (ParseError -> m b)     
       -> (a -> State s u -> ParseError -> m b) 
       -> (ParseError -> m b)     
       -> m b 
      } 

우리는 이렇게 할 수 있습니까?

newtype ParsecT m a s u  -- Only the order of s u m a is changed to m a s u. 
    = ParsecT {unParser :: forall b . 
       State s u 
       -> (a -> State s u -> ParseError -> m b) 
       -> (ParseError -> m b)     
       -> (a -> State s u -> ParseError -> m b) 
       -> (ParseError -> m b)     
       -> m b 
      } 

newtype을 정의 할 때 유형 변수의 순서에 관한 규칙이나 원칙이 있는지 궁금합니다.

+0

비슷한 수준의 질문은 여기에 있습니다 : http://stackoverflow.com/questions/5863128/ordering-of-parameters-to-make-use-of-currying – cheecheeo

답변

15

이 경우 ParsecT s u m __이 모나드가되기를 원하기 때문에 a이 마지막입니다. 그런 식으로 우리가 파서가 찾는 것은 이전에 발견 한 것에 따라 달라질 수 있습니다. u 마지막으로 온 경우 우리는 우리가 우리가 m 먼저 넣으면 ParsecT s u은 '모나드 트랜스포머'

class MonadTrans t where 
    lift :: m a -> t m a 

instance MonadTrans (ParsecT s u) where ... 

되고 싶어요 때문에

instance Monad m => Monad (ParsecT s u m) where ... 

m 다음 - 투 - 마지막이 인스턴스를 쓸 수 없습니다 가능하지 않을 것이다. su의 주문과 유사한 이유가없는 것으로 보입니다.

+1

'newtype' 순전히 형식 색인의 순서를 조작하여 여러 유형의 구멍에 'Functor'와 'Monad'에 대한 인스턴스를 제공 할 수 있습니다. –

+0

@applicative, 감사합니다. 나는 지금 본다. 나는 시도했지만 주문을 변경하고 원래 클래스 - 인스턴스 구조를 유지하는 것은 실제로 불가능합니다. – Znatz

관련 문제