<div dir="ltr"><div>These two pieces of code are not equivalent.</div><div><br></div><div> :{</div>
input = do<br>
eqatoms <- readFile "Parsing_File/eqatoms.out"<br>
return eqatoms<br>
:}<br><br>
:{<br>
main = do<br>
eqatoms <- readFile "Parsing_File/eqatoms.out"<br>
Parsec.parse species "test species" eqatoms<br>
return<br><div>
:}</div><div><br></div><div>You will have to do something like</div><div> :{</div><div> main = do<br>
eqatoms <- readFile "Parsing_File/eqatoms.out"<br>
let res = Parsec.parse species "test species" eqatoms</div><div> putStrLn (show res)<br></div><div> return</div><div> :}</div><div><br></div><div>And you will eventually clean it up by using a case statement to distinguish between success and error.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jan 26, 2022 at 7:41 AM Roger Mason <<a href="mailto:rmason@mun.ca">rmason@mun.ca</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
Warning: long post.<br>
<br>
I've worked my way through various parsing tutorials using either Parsec<br>
or ReadP. I reached a point where I need to try parsing one of the<br>
types of file for which I'm writing the parser. I have written parsers<br>
for various parts of this file:<br>
<br>
eqatoms.out:<br>
======================================================<br>
<br>
Species : 1 (Si)<br>
atom 1 is equivalent to atom(s)<br>
1 2 3<br>
atom 2 is equivalent to atom(s)<br>
1 2 3<br>
atom 3 is equivalent to atom(s)<br>
1 2 3<br>
<br>
Species : 2 (O)<br>
atom 1 is equivalent to atom(s)<br>
1 2 3 4 5 6<br>
atom 2 is equivalent to atom(s)<br>
1 2 3 4 5 6<br>
atom 3 is equivalent to atom(s)<br>
1 2 3 4 5 6<br>
atom 4 is equivalent to atom(s)<br>
1 2 3 4 5 6<br>
atom 5 is equivalent to atom(s)<br>
1 2 3 4 5 6<br>
atom 6 is equivalent to atom(s)<br>
1 2 3 4 5 6<br>
<br>
======================================================<br>
<br>
These are my imports:<br>
======================================================<br>
import qualified Text.Parsec as Parsec<br>
<br>
import Text.Parsec ((<?>))<br>
<br>
import Control.Applicative<br>
<br>
import Control.Monad.Identity (Identity)<br>
======================================================<br>
<br>
These are my parsers:<br>
======================================================<br>
:{<br>
species :: Parsec.Parsec String () (String,String)<br>
species = do<br>
--Parsec.char 'S'<br>
Parsec.string "Species"<br>
Parsec.spaces<br>
Parsec.char ':'<br>
Parsec.spaces<br>
digits <- Parsec.many1 Parsec.digit<br>
Parsec.spaces<br>
Parsec.char '('<br>
id <- Parsec.many1 Parsec.letter<br>
return (id,digits)<br>
:}<br>
<br>
:{<br>
atom = do<br>
Parsec.spaces<br>
Parsec.string "atom"<br>
Parsec.spaces<br>
digits <- Parsec.digit<br>
return digits<br>
:}<br>
<br>
:{<br>
equivalents = do<br>
Parsec.spaces<br>
digits <- Parsec.digit<br>
return digits<br>
:}<br>
======================================================<br>
<br>
Some simple tests:<br>
======================================================<br>
src = "oops"<br>
Parsec.parse species src "Species : 1 (Si)"<br>
<br>
Right ("Si","1")<br>
<br>
src = "Parsing_File/eqatoms.out"<br>
Parsec.parse atom src "atom 5 is equivalent to atom(s)"<br>
<br>
Right '5'<br>
<br>
src = "Parsing_File/eqatoms.out"<br>
Parsec.parse (Parsec.many1 equivalents) src " 1 2 3 4 5 6"<br>
<br>
: Right "123456"<br>
======================================================<br>
<br>
So, the individual parsers work as intended. However, parsing an actual<br>
file does not work.<br>
<br>
I define a function to return the file contents:<br>
======================================================<br>
:{<br>
input = do<br>
eqatoms <- readFile "Parsing_File/eqatoms.out"<br>
return eqatoms<br>
:}<br>
======================================================<br>
<br>
A test shows that my reader works:<br>
======================================================<br>
input<br>
<br>
: Species : 1 (Si)\n atom 1 is equivalent to atom(s)\n 1 2<br>
3\n atom 2 is equivalent to atom(s)\n 1 2 3\n atom 3 is<br>
equivalent to atom(s)\n 1 2 3\n\nSpecies : 2 (O)\n atom 1 is<br>
equivalent to atom(s)\n 1 2 3 4 5 6\n atom 2 is<br>
equivalent to atom(s)\n 1 2 3 4 5 6\n atom 3 is<br>
equivalent to atom(s)\n 1 2 3 4 5 6\n atom 4 is<br>
equivalent to atom(s)\n 1 2 3 4 5 6\n atom 5 is<br>
equivalent to atom(s)\n 1 2 3 4 5 6\n atom 6 is<br>
equivalent to atom(s)\n 1 2 3 4 5 6\n<br>
<br>
======================================================<br>
<br>
I attempt to parse the input:<br>
======================================================<br>
:{<br>
main = do<br>
eqatoms <- readFile "Parsing_File/eqatoms.out"<br>
Parsec.parse species "test species" eqatoms<br>
return<br>
:}<br>
<br>
Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| Prelude Parsec Text.Parsec Control.Applicative Control.Monad.Identity| <br>
<interactive>:250:3: error:<br>
,* Couldn't match type `Either Parsec.ParseError' with `IO'<br>
Expected type: IO (String, String)<br>
Actual type: Either Parsec.ParseError (String, String)<br>
,* In a stmt of a 'do' block:<br>
Parsec.parse species "test species" eqatoms<br>
In the expression:<br>
do eqatoms <- readFile "Parsing_File/eqatoms.out"<br>
Parsec.parse species "test species" eqatoms<br>
return<br>
In an equation for `main':<br>
main<br>
= do eqatoms <- readFile "Parsing_File/eqatoms.out"<br>
Parsec.parse species "test species" eqatoms<br>
return<br>
<br>
<interactive>:251:3: error:<br>
,* Couldn't match expected type `IO b'<br>
with actual type `a0 -> m0 a0'<br>
,* Probable cause: `return' is applied to too few arguments<br>
In a stmt of a 'do' block: return<br>
In the expression:<br>
do eqatoms <- readFile "Parsing_File/eqatoms.out"<br>
Parsec.parse species "test species" eqatoms<br>
return<br>
In an equation for `main':<br>
main<br>
= do eqatoms <- readFile "Parsing_File/eqatoms.out"<br>
Parsec.parse species "test species" eqatoms<br>
return<br>
,* Relevant bindings include<br>
main :: IO b (bound at <interactive>:248:3)<br>
======================================================<br>
<br>
Can someone please help me to get this to work?<br>
<br>
Thanks for reading to the end of this very long post.<br>
Roger<br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org" target="_blank">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</blockquote></div>