Я создаю деревья выражений Linq из F #, которые работают с имеющимся у меня настраиваемым типом данных. Тип представляет собой очень простое размеченное объединение, в котором обычные арифметические операторы перегружены. Но по какой-то причине я не могу создавать узлы арифметических выражений linq из-за того, что не может найти правильную перегрузку. Дело в том, что, клянусь, у меня это работало некоторое время назад, но я не могу понять, что я изменил, чтобы заставить его сломаться.
Прилагаю небольшой образец кода, показывающий проблему. В приведенном ниже типе данных оператор сложения перегружен. Использование перегруженного оператора работает как шарм, но когда я пытаюсь создать узел дерева выражения сложения с помощью Expression.Add (lhs, rhs), система выдает исключение с жалобой на то, что не может найти перегрузку для операции добавления.
Кто-нибудь знает, что я делаю не так?
Спасибо, Рикард
open System.Linq.Expressions
module DataType =
exception NotImplementedYet of string
type DataCarrier =
| ScalarCarrier of float
| VectorCarrier of float array
member this.Add(other) =
match (this, other) with
| ScalarCarrier(x), ScalarCarrier(y) -> ScalarCarrier(x + y)
| VectorCarrier(u), VectorCarrier(v) ->
VectorCarrier(Array.map2 (fun x y -> x + y) u v)
| _,_ -> raise (NotImplementedYet("No go!"))
static member (+) (lhs:DataCarrier, rhs) =
lhs.Add(rhs)
module Main =
let createAddOp (lhs:DataType.DataCarrier) (rhs:DataType.DataCarrier) =
let clhs = Expression.Constant(lhs)
let crhs = Expression.Constant(rhs)
Expression.Add(clhs, crhs)
(* no problems with this one *)
printf "Testing operator overloading: %A" (DataType.ScalarCarrier(1.0)
+ DataType.ScalarCarrier(2.0))
(* this throws an exception *)
printf "Testing expr construction %A" (Main.createAddOp
(DataType.ScalarCarrier(1.0))
(DataType.ScalarCarrier(2.0)))