![](/img/trans.png)
[英]Is it possible to recurse on a type hierarchy with distinct generic parameters in F#?
[英]Is it possible to pass parameters to F# modules?
我是F#的新手并且学习基础知识。
我有两个模块。 树数据结构的通用名称Tree
:
module Tree
let rec getDescendants getChildren node =
seq { yield node
for child in getChildren node do
yield! getDescendants getChildren child }
let isLeaf getChildren node = Seq.isEmpty (getChildren node)
let getLeaves getChildren node = getDescendants getChildren node
|> Seq.filter (isLeaf getChildren)
如您所见,所有函数都有一个getChildren
参数,该参数是枚举给定类型节点的子节点的函数。
第二个模块处理更具体的XML树案例:
module XmlTree
open System.Xml.Linq
let getXmlChildren (node : XElement) = node.Elements()
let getDescendants = Tree.getDescendants getXmlChildren
let getLeaves = Tree.getLeaves getXmlChildren
let isLeaf = Tree.isLeaf getXmlChildren
定义XML节点的特定getXmlChildren
函数并将其传递给getXmlChildren
的Tree
函数。
现在有很多代码重复。
是否有可能做到以下几点? (伪代码)
module XmlTree = Tree with getChildren = fun (node : XElement) -> node.Elements()
F#不支持仿函数,因此您无法将参数传递给F#模块。 在您的示例中,将生成节点子节点的函数传递给对象构造函数就足够了:
type Tree<'T>(childFn: 'T -> 'T seq) =
let getChildren = childFn
member x.getDescendants node =
seq { yield node
for child in getChildren node do
yield! x.getDescendants child }
member x.isLeaf node = node |> getChildren |> Seq.isEmpty
member x.getLeaves node = node |> x.getDescendants |> Seq.filter x.isLeaf
// Type usage
open System.Xml.Linq
let xmlTree = new Tree<XElement>(fun x -> x.Elements())
对于更复杂的案例, 继承是可行的方法。 特别是,您可以使用抽象成员getChildren
Tree<'T>
声明为抽象类,并在XmlTree
子类中重写该方法。
您不是使用模块执行此操作,而是使用泛型执行此操作
编辑 :
type tree<'t>(Children:seq<tree<'t>>)=
member x.isLeaf() = Seq.isEmpty (Children )
member x.getLeaves() =
getDescendants Children
|> Seq.filter (fun x -> x.isLeaf())
我遗漏了后代,但这应该足够了。 此外,某些类型注释不是必需的,但显示正在发生的事情
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.