F# strange type error message

116 views Asked by At

Can anyone tell me what the following error message means in F#:

Program.fs(1021,16): error FS0001: This expression was expected to have type
    FSI_0051.ExprTree
but here has type
    FSI_0061.ExprTree

It was the result of executing the following function:

let evaluate_tree tree =
    let rec helper tree =
        match tree with
        | Value(x) -> Value(x)
        | Node(l, op, r) -> evaluate (helper l) op (helper r)
    get_float (helper tree)

Line 1021 is the last line in the above function. In addition, I declared the following functions and types, before evaluate_tree:

type Operator =
    | Plus
    | Minus
    | Mult
    | Divide

type ExprTree =
    | Value of float
    | Node of ExprTree * Operator * ExprTree
    static member (-) (a, b) =
        match (a, b) with
        | (Value(x), Value(y)) -> Value(x - y)
    static member (+) (a, b) =
        match (a, b) with
        | (Value(x), Value(y)) -> Value(x + y)
    static member (/) (a, b) =
        match (a, b) with
        | (Value(x), Value(y)) -> Value(x/y)
    static member (*) (a, b) =
        match (a, b) with
        | (Value(x), Value(y)) -> Value(x*y)

Note that in the function below, when I did not add the line that says Node(_,_,_) -> 0.0 (commented), it gave the above error message. However, when I added that line, the error message went away (still I'd like to know what the error message means):

let get_float value =
    match value with
    | Value(x) -> x
    //| Node(_, _, _) -> 0.0

let evaluate (value1 : ExprTree) operator (value2 : ExprTree) =
    match operator with
    | Plus -> value1 + value2
    | Minus -> value1 - value2
    | Mult -> value1*value2
    | Divide -> value1/value2

let evaluate_tree tree =
    let rec helper tree =
        match tree with
        | Value(x) -> Value(x)
        | Node(l, op, r) -> evaluate (helper l) op (helper r)
    get_float (helper tree)

As a further note: evaluate_tree evaluates an expression tree. The expression tree contains the types defined in ExprTree: Value and Node. I think it might have to do with me not providing the case in get_float for when it's a Node (which I accounted for eventually). However, get_float will never evaluate a Node, not with the way I am using it, unless the tree is wrong (i.e. it will have an operator as a leaf node).

Thanks in advance!

1

There are 1 answers

2
Daniel Fabian On BEST ANSWER

Your error is caused by the fact, that each evaluation that execute in the FSI actually creates a dynamic assembly FSI_XXXX. So in fact, your function that you defined with ExprTree was maybe referring to FSI_0051.ExprTree whereas a function that you defined later and used ExprTree is now referring to FSI_0061.ExprTree.

What I typically do to fix the error, is just execute the definition of all my functions using ExprTree again, now that there is a newer FSI_0061.ExprTree and all should work.

You simply need to be aware, that each new evaluation with the same name will shadow the pre-existing symbol. On the other hand, they are still distinct symbols, hence the two names FSI_0051.ExprTree and FSI_0061.ExprTree.