Ich hasse es wirklich, diese Art von Frage zu stellen, aber ich bin am Ende meiner Weisheit hier. Ich schreibe einen inkrementellen Parser, aber aus irgendeinem Grund kann ich einfach nicht herausfinden, wie man funktor-Instanz dafür implementiert. Hier ist der Code dump:Ist dieser inkrementelle Parser ein Funktor, wenn ja, wie würde `fmap` implementiert?
Eingang Datentyp
Eingangsdatentyp durch Parser an den Koroutine ergibt. Es enthält die aktuelle Liste der Eingangs Zeichen von Koroutine und Zeilenende Bedingung
data Input a = S [a] Bool deriving (Show)
instance Functor Input where
fmap g (S as x) = S (g <$> as) x
Ausgangsdatentyp betrieben werden Datentyp
Ausgabe von Koroutine zu Parser ergibt. Es ist entweder ein Fehler bei Nachricht, Fertig [b] oder Partial ([a] -> Ausgabe ab), wobei [a] der aktuelle Puffer zurück an den Parser übergeben wird
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
Der Parser
Der Parser nimmt [a] und ergibt einen Puffer [a] bis Koroutine, welcher Ausgang AB ergibt zurück
data ParserI a b = PP { runPi :: [a] -> (Input a -> Output a b) -> Output a b }
Functor Implementation
Es scheint, wie alles, was ich zu tun haben, die Funktion g auf die Koroutine wird FMAP, wie folgt:
instance Functor (ParserI a) where
fmap g p = PP $ \as k -> runPi p as (\xs -> fmap g $ k xs)
Aber es prüft jedoch nicht Typ:
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
'ParserI' ist kein Funktor. Keine Instanz existiert. –
Oh X (Darf ich Sie bitten, zu erklären, warum? Und wie könnte ich es so umstrukturieren, dass es ein Funktor ist? Zum Beispiel in Attoparsec.Incremental (deprecated) hat die Coroutine einen ähnlichen Typ wie (c -> Input a -> Output ab), aber ich konnte nicht herausfinden, was das c für – chibro2
'fmap gp = PP $ \ as k -> runPi p als (\ xs -> fmap g $ k as)' <- das letzte 'as' da ist war beabsichtigt, ein 'xs' zu sein, war es nicht? –