2013-05-31 3 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

В этом случае a является последним, потому что мы хотим, чтобы мы были монадой, так что наши поисковые парсеры могут зависеть от того, что они нашли раньше, и так далее. Если u пришел наконец-то мы не могли бы написать

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

m рядом до последнего, потому что мы хотим ParsecT s u быть «монады» трансформатор

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

instance MonadTrans (ParsecT s u) where ... 

Если поставить m первый, этот экземпляр было бы невозможно. Кажется, что не существует какой-либо подобной причины для заказа s и u.

+1

Стоит воспитывать этот 'newtype' иногда используется исключительно для управления порядком индексов типа, чтобы вы могли предоставить экземпляры «Functor» и «Monad» на нескольких типизированных отверстиях. –

+0

@принципативный, спасибо. Я вижу сейчас. Я попытался, но на самом деле невозможно изменить порядок и сохранить исходную структуру экземпляра класса. – Znatz