Я считаю, что это упрощенная версия вашей проблемы (хотя вы исключаете слишком много кода, чтобы быть уверенным):
type T() = class end
type S =
static member Method(_:int, T) = 'c'
static member Method(_:string, T) = false
let curry f x y = f(x,y)
// won't work
T() |> curry S.Method 1
Как упоминает Брайан, перегрузка не очень хорошо работает с выводом типа,В частности, поскольку вывод типа F # работает слева направо, компилятор не использует тот факт, что 1
является int
при попытке выполнить поиск члена для S.Method
, что означает, что он не может идентифицироватьправильная перегрузка.На мой взгляд, у вас есть несколько вариантов:
- Использовать разные имена методов.Есть ли причина, по которой вы должны использовать
Property
для ссылки на несколько различных операций?Будет ли намного хуже использовать StringProperty
, IntProperty
и т. Д. Для каждой перегрузки?В целом, перегрузка усложняет жизнь компилятору (и часто человеку-сопровождающему).Кроме того, мне не нравится идея присвоения имени методу Property
, в любом случае ... Используйте явные параметры типа для curry
и укажите их.Например,
let curry<'a,'b,'c> f (x:'a) (y:'b) : 'c = f(x,y)
entityInfo |> curry<Expr<_ -> string>,_,_> EF.Property <@ fun z -> z.Path @>
Явно укажите тип EF.Property
:
entityInfo |> curry (EF.Property: Expr<_ -> string> * _ -> _) <@ fun z -> z.Path @>
Конечно, эти два последних варианта неочень краткие, поэтому они могут победить цель использования конвейерного стиля.