2015-06-06 11 views
2

Может кто-нибудь сказать мне, что означает следующее сообщение об ошибке в F #:F # сообщение об ошибке странного типа

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

Это был результат выполнения следующей функции:

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 является последним линии в вышеуказанной функции. Кроме того, я объявил следующие функции и типы, до 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) 

Обратите внимание, что в функции ниже, когда я не добавить строку, которая говорит Node(_,_,_) -> 0.0 (с комментариями), он дал выше сообщение об ошибке. Однако, когда я добавил эту строку, сообщение об ошибке ушло (я все еще хотел бы знать, что означает, что сообщение об ошибке):

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) 

В качестве дополнительной записки: evaluate_tree вычисляет дерево выражения. Дерево выражений содержит типы, определенные в ExprTree: Value and Node. Я думаю, что это может быть связано с тем, что я не предоставил дело в get_float, если это Node (который я в конечном счете учитывал). Тем не менее, get_float никогда не будет оценивать Node, а не тем, как я его использую, если дерево неверно (т. Е. Оно будет иметь оператор в качестве листового узла).

Заранее благодарен!

+3

Я думаю, что сообщение об ошибке означает, что в F # interactive существует конфликт между двумя версиями типов ExprTree, ранними оценками в интерактивном сеансе. Попробуйте сбросить интерактивный сеанс и переоценить все значения в скрипте – Petr

ответ

4

Ваша ошибка вызвана тем фактом, что каждая оценка, выполняемая в FSI, фактически создает динамическую сборку FSI_XXXX. На самом деле, ваша функция, которую вы определили с помощью ExprTree, возможно, имела в виду FSI_0051.ExprTree, тогда как функция, которую вы определили позже и которая используется ExprTree, теперь относится к FSI_0061.ExprTree.

Что я обычно делаю, чтобы исправить ошибку, просто выполните определение всех моих функций, используя ExprTree, теперь, когда есть новый FSI_0061.ExprTree, и все должно работать.

Вам просто нужно знать, что каждая новая оценка с тем же именем будет shadow уже существующий символ. С другой стороны, они все еще являются отдельными символами, поэтому два имени FSI_0051.ExprTree и FSI_0061.ExprTree.

+0

Извините за поздний ответ. Итак, вы имеете в виду, что в первый раз, когда я выполнил ** определение ** для 'ExprTree', он создал' FSI_0051.ExprTree', а во второй раз - 'FSI_0061.ExprTree'? Тогда ошибка, очевидно, возникла из-за того, что я определил некоторые функции и переменные перед определением второй, а некоторые после определения второй. Затем те, которые я определил после второго, ожидали 'FSI_0061.ExprTree', но другие переменные/функции все еще работали на' FSI_0051.ExprTree'? –

+1

Ya довольно много. В основном имена типов разрешаются во время определения определения. Поэтому, если вы не были родовыми, используется «старый» тип. –

Смежные вопросы