是否可以在类型定义中使用相同的运算符在运算符的右侧使用不同的类型?
通过名称plugElts定义| ==运算符可以很好地编译,但是稍后在模块RemoverTest中使用它会在右侧提供函数时失败error FS0002: This function takes too many arguments, or is used in a context where a function is not expected
。
module SampleOperators =
let inline (|==) (x: ^URel) (wires: ^Wires) =
(^URel: (static member plugElts: ^URel * ^Wires -> 'R) (x, wires))
module Remover =
open SampleOperators
type RemGroup<'G> = RemGroupPass | RemGroupAll | RemGroupExcept of 'G | RemGroupElts of 'G
type RemMap<'K,'P when 'K: comparison> =
RemGroup<Map<'K,'P>>
type RemFun<'K,'P when 'K: comparison> =
'K * 'P -> bool
type Rem<'K,'MapVal,'FunVal when 'K:comparison> =
| Map_ of RemMap<'K,'MapVal>
| Fun_ of RemFun<'K,'FunVal>
type X<'K,'P when 'K:comparison> =
{ id: 'K
vv: Rem<'K,'P,'P> }
static member inline plugElts (x:X<_,_>, ws:('K * 'P) seq) =
{x with vv = Map_ (RemGroupElts (Map.ofSeq ws))}
static member inline plugElts (x:X<_,_>, i:int) =
{x with vv = Map_ (RemGroupElts (Map.ofSeq [i,i]))}
static member inline plugElts (x:X<_,_>, fn:('K * 'P -> bool)) =
{x with vv = Fun_ fn}
module RemoverTest =
open Remover
open SampleOperators
let xxx1 () =
{id = 1; vv = Map_ RemGroupPass} |== [1,1] // compiles ok
let xxx2 () =
{id = 1; vv = Map_ RemGroupPass} |== 1 // compiles ok
let xxx3 () =
({id = 1; vv = Map_ RemGroupPass}:X<_,_>) |== (fun _ -> bool) // can't compile
有没有办法让这项工作没有在受歧视的联盟中包装右手边?
谢谢, 卡罗尔
编辑:使用int类型为右侧添加了重载
答案 0 :(得分:2)
当你在xxx3
中调用操作符时,你需要提供一个实际的函数 - 你现在拥有的只是类型声明的等价物。切换到以下内容,它将编译:
let xxx3 () =
({id = 1; vv = Map_ RemGroupPass}:X<_,_>) |== (fun _ -> true)
以下是您问题的更紧凑版本:
type MoreFun<'T> = 'T -> int
type X<'T> =
{
B: int
F: MoreFun<'T>
}
static member (|==) (a: X<_>, b: int) = { B = b; F = fun (f:int) -> b}
static member (|==) (a: X<_>, b: MoreFun<_>) = { a with F = b }
module Tests =
let one (f: int) = 1
let t1() = { B = 1; F = one } |== 2
// let t2() = { B = 1; F = one } |== (fun _ -> int) // Does not work
let three: MoreFun<_> = (fun _ -> 3)
let t3() = { B = 1; F = one } |== three
// You don't need to cast three to be of type MoreFun:
let t4() = { B = 1; F = one } |== (fun _ -> 3)