Jestem bardzo nowym uczniem Haskella. Mam wyraz robocza:Równoważniki ekspresji Haskella
do x <- try parseA <|> parseB
return x
który wydaje się doskonale działa (używam pakiet Parsec
, ale mam nadzieję, że kwestia ta nie ma nic wspólnego z jego funkcjonalności, o ile wiem, <|>
jest Parsec- zdefiniowany operator infiksów). parseA
i parseB
oba mają monadę typu Parser Foo
, podobnie jak całe wyrażenie.
Na podstawie tego, co już do tej pory przeczytać, wydaje się to powinno być równoważne
do return (try parseA <|> parseB)
i
do return $ try parseA <|> parseB
ale żaden z drugiej kompilacji, ale skarżą się na niedopasowane typów (błędów poniżej).
Moja druga próba przerobienia tego, jak
(try parseA <|> parse B) >>= return
wydaje się działać. Ale jeśli źle to zrozumiałem, proszę powiedz.
Moje pytanie brzmi, czy ktoś może wyjaśnić, dlaczego pierwsze trzy są różne. Jestem zdezorientowany, dlaczego nie są one równoważne. czego mi brakuje?
Błędy (w przypadku, gdy jest to właściwe, choć FWIW Nie szukam, aby „naprawić” mój kod - Mam wersję pracy, szukam, aby zrozumieć, w jaki sposób różne wersje):
do return (try parseA <|> parseB)
daje
parse.hs:76:11:
Couldn't match expected type ‘Foo’
with actual type ‘Text.Parsec.Prim.ParsecT
[Char]() Data.Functor.Identity.Identity Foo’
i
do return $ try parseA <|> parseB
daje
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)
Dziękuję, to była wskazówka, którą musiałem zrozumieć. Innym bitem, którego mi brakowało, jest to, że <- to nie tylko zadanie, to usuwa Monadę i zwraca typ bazowy, więc x <- y następnie foo x nie jest równoważne foo y.Doceniam kompleksową odpowiedź, Rein. – Ian