Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Types F#奇怪类型错误消息_Types_F#_Typeerror_Discriminated Union - Fatal编程技术网

Types F#奇怪类型错误消息

Types F#奇怪类型错误消息,types,f#,typeerror,discriminated-union,Types,F#,Typeerror,Discriminated Union,有人能告诉我以下错误消息在F#中的含义吗 这是执行以下函数的结果: 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) 第1021行是上述函数中的

有人能告诉我以下错误消息在F#中的含义吗

这是执行以下函数的结果:

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)
第1021行是上述函数中的最后一行。此外,在
evaluate\u 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)
注意,在下面的函数中,当我没有添加表示
节点(,,,->0.0
(注释)的行时,它给出了上述错误消息。但是,当我添加该行时,错误消息消失了(我仍然想知道错误消息的含义):

进一步说明:
evaluate\u tree
计算表达式树。表达式树包含在
ExprTree:Value和Node
中定义的类型。我想这可能是因为我没有在
get_float
中提供当它是
节点时的情况(我最终解释了这一点)。但是,
get\u float
将永远不会对
节点进行求值,不会以我使用它的方式进行求值,除非树是错误的(即,它将有一个操作符作为叶节点)


提前谢谢

您的错误是由以下事实引起的:在FSI中执行的每个计算实际上都会创建一个动态程序集FSI_XXXX。因此,实际上,您用
ExprTree
定义的函数可能指的是
FSI_0051.ExprTree
,而您后来定义并使用的
ExprTree
函数现在指的是
FSI_0061.ExprTree

我通常要做的是修复错误,只要再次使用
ExprTree
执行所有函数的定义,现在有了一个更新的
FSI_0061.ExprTree
,所有函数都应该可以工作


您只需要知道,每个具有相同名称的新求值都会对预先存在的符号产生阴影。另一方面,它们仍然是不同的符号,因此这两个名称
FSI_0051.ExprTree
FSI_0061.ExprTree

我认为错误消息意味着在F#interactive中,在交互会话中早期评估的ExprTree类型的两个版本之间存在冲突。请尝试重置交互式会话并重新评估脚本中的所有值抱歉答复太晚。那么您的意思是,第一次执行
ExprTree
的定义时,它创建了
FSI_0051.ExprTree
,第二次是
FSI_0061.ExprTree
?然后错误明显出现了,因为我在定义第二个之前定义了一些函数和变量,在定义第二个之后定义了一些函数和变量。然后,我在第二个变量之后定义的变量应该是
FSI_0061.ExprTree
,但其他变量/函数仍然在
FSI_0051.ExprTree
上运行。基本上,类型名是在定义的计算时解析的。因此,除非您是泛型的,否则将使用“old”类型。
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)
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)