我正在为(有效地)排列库构建一个库;目标是允许您指定和组合n个元素上的排列.因此,例如,我希望能够执行以下操作:
let p1 = Permutation([4,3,2,1])
let p2 = Permutation([1,3,2,4])
p1 * p2 // -> Permutation([4,2,3,1])
一般来说,只有组成相同大小的排列才有意义.因此,例如:
let p3 = Permutation([1,2,3])
p1 * p3 // Error
显然,我可以在作文时判断大小,然后抛出异常或返回nil
;但这两个选项都涉及更多的样板(要么用try
标记每个作文,要么解包每个结果).因为组合不同长度的排列从来没有意义,所以我更希望有一个编译时错误--本质上,我希望不同长度的排列具有不同的类型.
我可以指定有限数量的类型--我的最终用例可能只关心有限的大小范围.但是,最终还会有其他类型的类型(例如,排列序列或排列的语义类型子集)将应用相同的限制-所以我更喜欢以某种通用的方式进行类型判断.
(如果有帮助,基本上我要寻找的是一种近似Julia的NTuple
个类型的方法,这些类型由元素的数量来参数化.)
我try 过的东西
到目前为止,我最好的try 涉及虚拟长度的"类型"(即每个长度有一个单独的不可实例化的类型):
protocol LengthProtocol { }
enum Three: LengthProtocol { }
enum Four: LengthProtocol { }
struct Permutation<Length: LengthProtocol> {
// ...
static func *<S: LengthProtocol>(lhs: Permutation<S>, rhs: Permutation<S>) -> Permutation<S> {
// ...
}
}
然而,类型推断似乎失败了,如下所示:
let p1 = Permutation<Three>([1,2,3])
let p2 = Permutation<Three>([1,3,2])
p1 * p2 // ERROR: Cannot infer generic paramter S