2013-05-31 36 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 
      } 

我想知道当我们定义一个新类型时,是否存在关于类型变量顺序的规则或原则。

+0

在价值水平的类似问题在这里:http://stackoverflow.com/questions/5863128/ordering-of-parameters-to-make-use-of-currying – cheecheeo

回答

15

在这种情况下,a是最后一个,因为我们希望ParsecT s u m __成为monad,那么,我们的解析器查找的内容可能取决于他们之前找到的内容等等。如果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第一,这种情况下将不可能。 su的排序似乎没有任何类似的原因。

+1

值得提出的'newtype'有时纯粹用于操纵类型索引的顺序,以便您可以在多个类型的孔上提供'Functor'和'Monad'的实例。 –

+0

@applicative,谢谢。我现在明白了。我试过了,但实际上不可能改变顺序并保留原来的类实例结构。 – Znatz

相关问题