Ich bin ein sehr neuer Haskell Lerner. Ich habe einen Arbeits Ausdruck:Haskell Expression Equivalents
do x <- try parseA <|> parseB
return x
, die perfekt zu funktionieren scheint (Ich bin das Parsec
Paket, aber ich hoffe, dass diese Frage hat nichts mit seiner Funktionalität zu tun, soweit ich weiß, <|>
ist ein Parsec- definierter Infix-Operator). parseA
und parseB
haben beide den Parser Foo
Monad-Typ, ebenso wie der gesamte Ausdruck.
Nach dem, was ich bisher gelesen habe, scheint es diese
do return (try parseA <|> parseB)
und
do return $ try parseA <|> parseB
aber keines der letzteren Kompilierung gleichwertig sein sollte, sie klagen über nicht übereinstimmen Typen (Fehler unten).
Mein anderer Versuch, dies zu umschreiben, als
(try parseA <|> parse B) >>= return
scheint zu funktionieren. Aber wenn ich das auch falsch verstanden habe, sag es bitte.
Also meine Frage ist, kann jemand erklären, warum die ersten drei unterschiedlich sind. Ich bin verwirrt, warum sie nicht gleichwertig sind. Was vermisse ich?
Fehler (falls dies relevant ist, obwohl FWIW ich nicht bin auf der Suche nach meinem Code ‚fix‘ - Ich habe eine funktionierende Version, ich bin auf der Suche zu verstehen, wie die Versionen unterscheiden):
do return (try parseA <|> parseB)
gibt
parse.hs:76:11:
Couldn't match expected type ‘Foo’
with actual type ‘Text.Parsec.Prim.ParsecT
[Char]() Data.Functor.Identity.Identity Foo’
und
do return $ try parseA <|> parseB
gibt
parse.hs:76:3:
Couldn't match type ‘Text.Parsec.Prim.ParsecT
[Char]() Data.Functor.Identity.Identity Foo’
with ‘Foo’
Expected type: Parser Foo
Actual type: Text.Parsec.Prim.ParsecT
String
()
Data.Functor.Identity.Identity
(Text.Parsec.Prim.ParsecT
[Char]() Data.Functor.Identity.Identity Foo)
Danke, das war der Tipp, den ich verstehen musste. Das andere Bit, das mir fehlte, ist das <- ist nicht nur eine Zuweisung, es entfernt die Monade und gibt den zugrundeliegenden Typ zurück, also x <- y dann ist foo x nicht äquivalent zu foo y.Ich schätze die umfassende Antwort, Rein. – Ian