I'm studying some F# and trying to implement a parser combinator like in this tutorial; after some copy and paste of the proposed solution, I tried to customize it by myself.
Surely there's something I missed but the compiler gives me a weird error message.
type T<'a> =
| A of string
| B of 'a
let foo a b =
match a with
| A s as x -> x
| B i ->
match b with
| A s as x -> x
| B j ->
B (i, j)
The code above is a generalization of the issue I found: the error is notified in the last result (the B branch of the innermost matching expression):
error FS0001: Type mismatch. Expecting a
'a
but given a
'a * 'b
The resulting type would be infinite when unifying ''a' and ''a * 'b'
But if I don't use the as
pattern:
let foo a b =
match a with
| A s -> A s // it can also be '| A s as x -> A s'
| B i ->
match b with
| A s -> A s
| B j ->
B (i, j)
then the compiler is happy again.
I don't get why I have to recreate the same logical result if it is already there.
In
A s as x -> x
x
has type T<'a>
while the required return type for foo
is T<('a * 'a)>
. Even though the A
case does not contain any values of 'a
it does not have a polymorphic type like forall 'a . T<'a>
. In your second example you are creating a new instance of A
which can have the required type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With