F# 单一案件歧视性结合的目的
我正在定义一元可观察/反应解析器。这与普通解析器的行为完全不同,因为它是一个连续查询。基本类型为:F# 单一案件歧视性结合的目的,f#,monads,discriminated-union,F#,Monads,Discriminated Union,我正在定义一元可观察/反应解析器。这与普通解析器的行为完全不同,因为它是一个连续查询。基本类型为: IObservable<'a> -> IObservable<'b> 问题是:这只是按照惯例,还是为了以后的扩展,或者即使定义从未改变,也有理由这样做 附加问题:如果只是为了更方便的类型签名,为什么不使用类型别名: type Pattern<'a,'b> = IObservable<'a> -> IObservable<'b>
IObservable<'a> -> IObservable<'b>
问题是:这只是按照惯例,还是为了以后的扩展,或者即使定义从未改变,也有理由这样做
附加问题:如果只是为了更方便的类型签名,为什么不使用类型别名:
type Pattern<'a,'b> = IObservable<'a> -> IObservable<'b>
type Vector = float * float
// val add : float * float -> float * float -> Vector
let add ((x1, y1): Vector) ((x2, y2): Vector): Vector = (x1 + y1, x2 + y2)
type Pattern=IObservable
我在这方面做了很多工作,还没有发现不使用DU会影响可组合性的情况。据我所知,单例区分联合类型提供了一个与您的问题域在语义上相关的名称,另一个通用后端类型的名称是“string” 这是一个针对语义的轻度抽象泄漏修复程序,只是AFAIK编译器没有保留有关类型缩写的信息,所以您根本无法从类型推断中获益。类型签名可以理解为程序规范;让类型检查器完成它们的工作是确保程序正确性的好方法 在类型别名的情况下,需要在所有位置显式指定类型注释:
type Pattern<'a,'b> = IObservable<'a> -> IObservable<'b>
type Vector = float * float
// val add : float * float -> float * float -> Vector
let add ((x1, y1): Vector) ((x2, y2): Vector): Vector = (x1 + y1, x2 + y2)
但在使用DU时,它并不能提供透明性:
type Vector = V of float * float
// val add : Vector -> Vector -> Vector
let add (V(x1, y1)) (V(x2, y2)) = V(x1 + y1, x2 + y2)
在复杂的程序中,清晰的类型签名确实使维护可组合性变得更容易
不仅向单个案例DU添加更多案例更简单,而且使用成员和静态方法扩展DU也更容易。例如,您经常覆盖
ToString()
以进行漂亮的打印 我认为那不是真的。这就是类型别名。一个区分大小写的并集是一个完整的类,在本例中,它包装了一个函数(或C#talk中的委托)。但是我不知道还有什么用。。。另外,请注意,您可以向联合类型添加一些方法。谢谢,这实际上是一个非常具体的原因。绝对不想到处输入IObservable
而不是模式
。许多月后的后续报道。我确实在联盟中添加了第二个案例,因此宇宙处于平衡状态。