'Anonymous type variables are not permitted in this declaration' 在 F# 中将参数添加到已区分的联合案例时出错
'Anonymous type variables are not permitted in this declaration' error when adding parameters to discriminated union cases in F#
所以我有一些(我假设相当不寻常)用于构建函数树的代码。这是现在:
type FunctionTree<'Function> =
| BranchNode of seq<FunctionTree<'Function>>
| Leaf of (a:'Function -> unit) with
member __.Execute() = do a
表达式 a:'Function -> unit
让编译器出错,给我错误 'Anonymous type variables are not permitted in this declaration' 我不知道为什么。我试过向 BranchNode 添加一个变量,在表达式周围添加(令人讨厌的)双括号,但似乎没有任何效果。
编译器错误问题的答案
这不编译...
Leaf of (a:'Function -> unit)
...因为区分的字段名称可以添加到 DU 案例的 types,而不是 function types[=56= 的类型] 在 DU 案例中。相比之下,这编译...
Leaf of a: ('Function -> unit)
...因为字段名称 a
被用于命名类型 (Function -> unit)
.
关于代码的补充讨论
但是,还有一个问题。正如您的代码所暗示的那样,您要添加的成员 Execute
并未添加到叶节点。它被添加到整个功能树中。因此,您将无法访问 Execute
实现中的标签 a
。可以这样想...
type FunctionTree<'Function> =
| BranchNode of seq<FunctionTree<'Function>>
| Leaf of a: ('Function -> unit)
with member __.Execute() = do a
... 成员向左移动以阐明它适用于整个联合,而不仅仅是叶案例。这就解释了为什么上面的代码现在有一个不同的编译器错误...a is not defined
。字段名称 a
用于阐明 Leaf case 的实例化。字段名称 a
在其他地方不可用。
let leaf = Leaf(a: myFunc)
因此,您的 Execute
成员无法使用标签 a
。你需要做这样的事情......
with member x.Execute(input) =
match x with
| BranchNode(b) -> b |> Seq.iter(fun n -> n.Execute(input))
| Leaf(f) -> f(input) |> ignore
注意上面代码中的x
值是一个FunctionTree
.
替代实施
我们可以继续前进。但是,我认为以下内容可能会实现您的目标:
type FunctionTree<'T> =
| BranchNode of seq<FunctionTree<'T>>
| LeafNode of ('T -> unit)
let rec evaluate input tree =
match tree with
| LeafNode(leaf) -> leaf(input)
| BranchNode(branch) -> branch |> Seq.iter (evaluate input)
BranchNode([
LeafNode(printfn "%d")
LeafNode(printfn "%A")
])
|> evaluate 42
所以我有一些(我假设相当不寻常)用于构建函数树的代码。这是现在:
type FunctionTree<'Function> =
| BranchNode of seq<FunctionTree<'Function>>
| Leaf of (a:'Function -> unit) with
member __.Execute() = do a
表达式 a:'Function -> unit
让编译器出错,给我错误 'Anonymous type variables are not permitted in this declaration' 我不知道为什么。我试过向 BranchNode 添加一个变量,在表达式周围添加(令人讨厌的)双括号,但似乎没有任何效果。
编译器错误问题的答案
这不编译...
Leaf of (a:'Function -> unit)
...因为区分的字段名称可以添加到 DU 案例的 types,而不是 function types[=56= 的类型] 在 DU 案例中。相比之下,这编译...
Leaf of a: ('Function -> unit)
...因为字段名称 a
被用于命名类型 (Function -> unit)
.
关于代码的补充讨论
但是,还有一个问题。正如您的代码所暗示的那样,您要添加的成员 Execute
并未添加到叶节点。它被添加到整个功能树中。因此,您将无法访问 Execute
实现中的标签 a
。可以这样想...
type FunctionTree<'Function> =
| BranchNode of seq<FunctionTree<'Function>>
| Leaf of a: ('Function -> unit)
with member __.Execute() = do a
... 成员向左移动以阐明它适用于整个联合,而不仅仅是叶案例。这就解释了为什么上面的代码现在有一个不同的编译器错误...a is not defined
。字段名称 a
用于阐明 Leaf case 的实例化。字段名称 a
在其他地方不可用。
let leaf = Leaf(a: myFunc)
因此,您的 Execute
成员无法使用标签 a
。你需要做这样的事情......
with member x.Execute(input) =
match x with
| BranchNode(b) -> b |> Seq.iter(fun n -> n.Execute(input))
| Leaf(f) -> f(input) |> ignore
注意上面代码中的x
值是一个FunctionTree
.
替代实施
我们可以继续前进。但是,我认为以下内容可能会实现您的目标:
type FunctionTree<'T> =
| BranchNode of seq<FunctionTree<'T>>
| LeafNode of ('T -> unit)
let rec evaluate input tree =
match tree with
| LeafNode(leaf) -> leaf(input)
| BranchNode(branch) -> branch |> Seq.iter (evaluate input)
BranchNode([
LeafNode(printfn "%d")
LeafNode(printfn "%A")
])
|> evaluate 42