No subject


Sun Oct 23 10:51:38 CEST 2011


two argument types as well as the result type. We also see that (<|>) is a
right-associative infix operator. So, this means the offending line could
be parenthesized as pArit <|> (pBool <|> pEqual), which fits the second
part of the type error, pBool <|> pEqual. Looking at the types of those, we
see:

*Expr> :t pBool
pBool :: ParsecT String () Data.Functor.Identity.Identity (Expr Bool)
*Expr> :t pEqual
pEqual :: ParsecT String () Data.Functor.Identity.Identity (Expr Double)

As we saw with the type of (<|>), these two types should be the "same" (as
in unifiable). However, they are not, because the two type arguments to the
Expr GADT differ: Bool in one case and Double in the other. GHC cannot
"match" (unify) these types.

Now, to the goal of your project: You say that the parser "should be able
to parse any form of expressions," but since you are using a GADT with the
expected expression types in the result index of each constructor, you can
only define parsers that each parse an expression of a single type. That
is, you can have a parser for Expr Bool and a parser for Expr Double, but
these parsers can not be alternatives of another Expr and still have a
valid type. This is, of course, the reason for using the type index as it
is: you don't want Bool where you expect Double and vice versa.

As a general comment, you may want to consider simplifying your goal to
parsing only expressions of type Double. Then, what happens to your Bool
constructors? Well, you could drop them, or you could extend your GADT with
an "if" constructor that takes a boolean condition with Double alternatives.

Regards,
Sean

--14dae93408915a1e4204bf0db321
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hi Romildo,<br><br><div class=3D"gmail_quote">On Wed, May 2, 2012 at 3:08 P=
M, <span dir=3D"ltr">j.romildo</span>=A0wrote:<br><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div class=3D"im">

You are right in the sense that I cannot mix Expr Bool and Expr Double</div=
>
in a (O op l r) expression.<br>
<br>
But the parser should be able to parse any form of expressions. So I<br>
rewrite my program to take this into account.<br>
<br>
The new versions still does not compile:<br>
<br>
Expr.hs:27:23:<br>
<div class=3D"im"> =A0 =A0Couldn&#39;t match expected type `Double&#39; wit=
h actual type `Bool&#39;<br>
</div> =A0 =A0Expected type: ParsecT<br>
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 String () Data.Functor.Identity.Id=
entity (Expr Double)<br>
 =A0 =A0 =A0Actual type: ParsecT<br>
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 String () Data.Functor.Identity.Id=
entity (Expr Bool)<br>
 =A0 =A0In the first argument of `(&lt;|&gt;)&#39;, namely `pBool&#39;<br>
 =A0 =A0In the second argument of `(&lt;|&gt;)&#39;, namely `pBool &lt;|&gt=
; pEqual&#39;<br></blockquote><div><br></div><div>You appear to still be ha=
ving the same problem. Perhaps this because you don&#39;t quite understand =
the type error? Let me help you dissect it. Since this is a type error, I&#=
39;m not going to assume anything about what should or should not work. I&#=
39;ll only look at the types.</div>

<div><br></div><div>First, let&#39;s comment out the offending line, so tha=
t your file type-checks:</div><div><br></div><div>Line 27: -- pExpr =A0 =A0=
 =3D pArit &lt;|&gt; pBool &lt;|&gt; pEqual</div><div><br></div><div>Next, =
let&#39;s look at each of the components relevant to the type error. The fi=
rst mentioned is (&lt;|&gt;). In GHCi, we can find out more information abo=
ut that:</div>

<div><div><br></div><div>*Expr&gt; :i (&lt;|&gt;)</div><div>(&lt;|&gt;) :: =
ParsecT s u m a -&gt; ParsecT s u m a -&gt; ParsecT s u m a</div><div>=A0 <=
span class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>-- Defined =
in Text.Parsec.Prim</div>

<div>infixr 1 &lt;|&gt;</div></div><div><br></div><div>From this, we see th=
at the same type parameters to ParsecT are used in the two argument types a=
s well as the result type. We also see that (&lt;|&gt;) is a right-associat=
ive infix operator. So, this means the offending line could be parenthesize=
d as=A0pArit &lt;|&gt; (pBool &lt;|&gt; pEqual), which fits the second part=
 of the type error,=A0pBool &lt;|&gt; pEqual.=A0Looking at the types of tho=
se, we see:</div>

<div><br></div><div><div>*Expr&gt; :t pBool=A0</div><div>pBool=A0:: ParsecT=
 String () Data.Functor.Identity.Identity (Expr Bool)</div><div>*Expr&gt; :=
t pEqual=A0</div><div>pEqual=A0:: ParsecT String () Data.Functor.Identity.I=
dentity (Expr Double)</div>

</div><div><br></div><div>As we saw with the type of (&lt;|&gt;), these two=
 types should be the &quot;same&quot; (as in unifiable). However, they are =
not, because the two type arguments to the Expr GADT differ: Bool in one ca=
se and Double in the other. GHC cannot &quot;match&quot; (unify) these type=
s.</div>

<div><br></div><div>Now, to the goal of your project: You say that the pars=
er &quot;should be able to parse any form of expressions,&quot; but since y=
ou are using a GADT with the expected expression types in the result index =
of each constructor, you can only define parsers that each parse an express=
ion of a single type. That is, you can have a parser for Expr Bool and a pa=
rser for Expr Double, but these parsers can not be alternatives of another =
Expr and still have a valid type. This is, of course, the reason for using =
the type index as it is: you don&#39;t want Bool where you expect Double an=
d vice versa.</div>

<div><br></div><div>As a general comment, you may want to consider simplify=
ing your goal to parsing only expressions of type Double. Then, what happen=
s to your Bool constructors? Well, you could drop them, or you could extend=
 your GADT with an &quot;if&quot; constructor that takes a boolean conditio=
n with Double alternatives.</div>

<div><br></div><div>Regards,</div><div>Sean</div></div>

--14dae93408915a1e4204bf0db321--



More information about the Haskell-Cafe mailing list