2013-05-31 19 views
10

Ad esempio, ParsecT ha più variabili di tipo nella sua definizione.Qual è la regola dell'ordine di più variabili di tipo in 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 
      } 

Possiamo farlo in questo modo?

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 
      } 

mi chiedo se c'è una regola o principio circa l'ordine delle variabili di tipo quando si definisce una newtype.

+0

Una domanda simile a livello di valore è qui: http://stackoverflow.com/questions/5863128/ordering-of-parameters-to-make-use-of-currying – cheecheeo

risposta

15

In questo caso, a è l'ultimo perché vogliamo che ParsecT s u m __ sia una monade, in questo modo, ciò che i nostri parser cercano può dipendere da ciò che hanno trovato prima e così via. Se u è venuto lo scorso non siamo riusciti a scrivere

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

m è next-to-ultimo perché vogliamo ParsecT s u di essere un 'monade trasformatore'

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

instance MonadTrans (ParsecT s u) where ... 

Se mettiamo la prima m, questa istanza non sarebbe possibile Non sembra esserci alcun motivo analogo per l'ordinazione di s e u.

+1

Vale la pena portare su quel 'newtype' a volte usato esclusivamente per manipolare l'ordine degli indici di tipo in modo da poter fornire istanze per 'Functor' e' Monad' su più buchi digitati. –

+0

@applicativo, grazie. Ora vedo. Ho provato ma è in realtà impossibile modificare l'ordine e preservare la struttura originale delle istanze di classe. – Znatz