この種の質問をするのは本当に嫌いですが、ここで知恵が尽きてしまいました。インクリメンタルパーサーを書いていますが、何らかの理由でファンクターインスタンスを実装する方法がわかりません。コードダンプは次のとおりです。
入力データ型
入力は、パーサーによってコルーチンに生成されたデータ型です。コルーチンと行末条件によって操作されている入力文字の現在のリストが含まれています
data Input a = S [a] Bool deriving (Show)
instance Functor Input where
fmap g (S as x) = S (g <$> as) x
出力データ型
出力は、コルーチンによってパーサーに生成されるデータ型です。これは、Failed メッセージ、Done [b]、または Partial ([a] -> Output ab) のいずれかです。ここで、[a] はパーサーに戻された現在のバッファーです。
data Output a b = Fail String | Done [b] | Partial ([a] -> Output a b)
instance Functor (Output a) where
fmap _ (Fail s) = Fail s
fmap g (Done bs) = Done $ g <$> bs
fmap g (Partial f) = Partial $ \as -> g <$> f as
パーサー
パーサーは [a] を受け取り、バッファー [a] をコルーチンに生成します。コルーチンは出力 ab を返します。
data ParserI a b = PP { runPi :: [a] -> (Input a -> Output a b) -> Output a b }
ファンクターの実装
次のように、関数 g をコルーチンに fmap するだけでよいようです。
instance Functor (ParserI a) where
fmap g p = PP $ \as k -> runPi p as (\xs -> fmap g $ k xs)
しかし、それはチェックをタイプしません:
Couldn't match type `a1' with `b'
`a1' is a rigid type variable bound by
the type signature for
fmap :: (a1 -> b) -> ParserI a a1 -> ParserI a b
at Tests.hs:723:9
`b' is a rigid type variable bound by
the type signature for
fmap :: (a1 -> b) -> ParserI a a1 -> ParserI a b
at Tests.hs:723:9
Expected type: ParserI a b
Actual type: ParserI a a1