Recursion F#型递归树结构

Recursion F#型递归树结构,recursion,f#,tree,Recursion,F#,Tree,我在F#还是一个新手,我一直在试图弄清楚如何制作我自己的类型,它可以容纳任意数量的“A”,如果它最终应该是一个值的话 例如,它可能类似于: A(A(A(A(A(0))))). 如果我尝试这样创建类型,我会尝试这样声明它: type test = | A of int | A of test;; type test = | B of int | A of test;; 它告诉我,我不能两次声明相同的类型,因为

我在F#还是一个新手,我一直在试图弄清楚如何制作我自己的类型,它可以容纳任意数量的“A”,如果它最终应该是一个值的话

例如,它可能类似于:

A(A(A(A(A(0))))).
如果我尝试这样创建类型,我会尝试这样声明它:

type test = 
          | A of int
          | A of test;;
type test = 
          | B of int
          | A of test;;
它告诉我,我不能两次声明相同的类型,因为我有重复的类型。有没有办法解决这个问题,或者我真的需要将最后一个节点改名为:

type test = 
          | A of int
          | A of test;;
type test = 
          | B of int
          | A of test;;
结果将是:

A(A(A(A(B(0)))))

有什么帮助吗?

我不确定这是否符合您的其他限制(您没有告诉我们),但这可以通过将类型设置为泛型来轻松实现:

type test<'a> = A of 'a

let a0 = A 0
let a1 = A(A(0))
let a5 = A(A(A(A(A(0)))))

typetest其他人建议了一些变通方法,但我建议您确实不希望
A(A(A(A(0щщ))
以您认为的方式进行,而
A(A(A(B(0щщщ)
(该语言正试图强迫您这样做)是一个更好的选择)

让我们看看你的树类型。您有两种不同的东西:一种是包含其他树节点的树节点,另一种是包含数据的树节点。你要做的是用同一个名字来称呼这两件事:

type test =
          | A of int
          | A of test
这些名字并不是特别具有描述性。让我们把它们重命名为

type Tree =
          | Node of int
          | Node of Tree
现在,在处理树结构时,需要区分“Node of int”和“Node of tree”的情况:如果是“Node of int”,则需要(比如)提取int并在计算中使用它。但是如果它是一个“树的节点”,你会想(比如)深入到树的结构中,最终到达彩虹尽头的那罐金子。。。我的意思是,树末端的int

因此,您需要编写一个
匹配
结构,如下所示:

let rec diveTree calculation node =
    match node with
        | Node a -> match a with
                    | :? int -> calculation a
                    | :? Tree -> diveTree calculation a
但是,如果我们做了F#试图强迫你做的事情,并对“包含一个int”和“包含另一棵树”案例使用了不同的名称,会怎么样?那么您的类型将如下所示:

type Tree =
          | LeafNode of int
          | TreeNode of Tree
let rec diveTree calculation node =
    match node with
        | LeafNode a -> calculation a
        | TreeNode a -> diveTree calculation a
匹配
结构将如下所示:

type Tree =
          | LeafNode of int
          | TreeNode of Tree
let rec diveTree calculation node =
    match node with
        | LeafNode a -> calculation a
        | TreeNode a -> diveTree calculation a

我想你会发现后者比前者更容易阅读和理解。这就是为什么F#要求你对不同的歧视性结合使用不同的标签。

一个替代方案是
类型测试=测试选项的一个
注意,更好的设计是使其通用:
类型树型适合你的长答案:)它也解决了很多问题,而且总是很好的当人们试图帮助时:)这不是我想要的。我需要它是同一类型的。为什么我需要它像这样是一个较长的故事来解释:)但是,再次感谢你的回答:)“我需要它是相同的类型。”但事实上,正如费奥多·索金在他的回答中指出的,它们将是不同的类型。叶节点的类型为
test
,树节点的类型为
test
。我想这会给你带来麻烦。您能否扩展您的问题以解释为什么希望树节点和叶节点属于同一类型?我有一种感觉,有一种更好的方法来做你想做的事情,但在我们知道你真正想解决的问题之前,我们无法给你更好的建议。非常感谢!这正是我要找的。我一直在f#books和网上读很多东西,根本找不到这样的答案。我认为我这本书写得不太好。再次非常感谢:)!如果我的回答帮助了你,你会考虑接受吗?哦,对不起。我第一次写问题。现在应该完成了谢谢:)@ANACoder-你看到了吗?这是迄今为止我找到的最好的参考书。我建议你从这一系列开始,然后阅读你喜欢的任何其他系列。我想你会从那个网站学到很多东西。