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

この場合、ParsecT s u m __がモナドであることが望ましいので、aが最後になります。そのようにして、私たちのパーサが探しているものは、以前に見つかったものに依存するなどです。 uが最後に来たなら、私たちは

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

mを書くことができませんでした私たちはm最初に、このインスタンスを配置する場合ParsecT s uは、「モナド変換子」

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

instance MonadTrans (ParsecT s u) where ... 

になりたいので、最後からです可能ではありません。 suの注文には、同様の理由はないようです。

+1

「newtype」を呼び出す価値は時々です純粋に型インデックスの順序を操作するために、複数の型付きの穴に 'Functor'と' Monad'のインスタンスを提供することができます。 –

+0

@applicative、ありがとうございます。私は今参照してください。私は試しましたが、実際には順序を変更して元のクラスインスタンスの構造を保持することは不可能です。 – Znatz

関連する問題