Swift中基于协议的通用树结构

时间:2016-07-18 14:08:58

标签: swift generics protocols

我一直在研究另一种语言的一些代码示例(Haskell& C#是具体的),而且我遇到了一个与Swift等效的问题。

根据Haskell的定义,我们有:

data Tr a = Lf a | Br (Tr a) (Tr a)

从C#开始,我们有:

public abstract class Tr<T> { }

public class Lf<a> : Tr<a> {
    public a contents { get; set; }
}

public class Br<a> : Tr<a> {
    public Tr<a> left { get; set; }
    public Tr<a> right { get; set; }
}

因此,树是具有泛型类型的内容的叶子,或者是具有左和上的分支的树。对树。

我遇到了Swift中的类型系统,所以我不确定应该采用什么样的形式。我有:

protocol Tree {
    associatedtype Element: CustomStringConvertible
}

struct Leaf<LeafElement: CustomStringConvertible>: Tree {
    typealias Element = LeafElement
    let content: Element
}

struct Branch<BranchElement: CustomStringConvertible>: Tree {
    typealias Element = BranchElement
    let left: Tree<Element>
    let right: Tree<Element>
}

在这一点上,上面是我的头撞在墙上的许多次迭代,所以在这一点上它可能已经过时了。 Leaf似乎很好,但Branch失败了

Protocol 'Tree' can only be used as a generic constraint because it has Self or associated type requirements

建议将不胜感激。

1 个答案:

答案 0 :(得分:1)

直接从C#翻译:

@property(retain, readwrite) NSTextField *toField;
@property(retain, readwrite) NSTextField *fromField;
@property(retain, readwrite) NSTextField *subjectField;
@property(retain, readwrite) NSTextField *fileAttachmentField;
@property(retain, readwrite) NSTextView *messageContent;

- (IBAction)sendEmailMessage:(id)sender;
- (IBAction)chooseFileAttachment:(id)sender;

使用Swift的public class Tr<A> { private init() {} } public class Lf<A> : Tr<A> { public var contents: A init(contents: A) { self.contents = contents } } public class Br<A> : Tr<A> { public var left: Tr<A> public var right: Tr<A> init(left: Tr<A>, right: Tr<A>) { self.left = left self.right = right } } let leaf1 = Lf(contents: 0) let leaf2 = Lf(contents: 1) let branch1 = Br(left: leaf1, right: leaf2) let leaf3 = Lf(contents: 2) let branch2 = Br(left: leaf3, right: branch1)

inidirect enum