Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# matching expression and 'as' pattern

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.

like image 343
Atropo Avatar asked Jun 28 '17 15:06

Atropo


1 Answers

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.

like image 173
Lee Avatar answered Nov 15 '22 10:11

Lee