有没有办法在 F# 中处理这个 DU 中的标准字段?
is there a way to handle standard fields in this DU, in F#?
我这里有一些非常难看的代码:
type AnalysisEvent =
| ZoneStart of DateTime * ConsolidationZone
| ZoneEndExitHigh of DateTime * ConsolidationZone
| ZoneEndExitLow of DateTime * ConsolidationZone
| ZoneContraction of DateTime * ConsolidationZone
| ZoneExpansion of DateTime * ConsolidationZone
| FairPriceCrossHigh of DateTime * FairPriceLine
| FairPriceCrossLow of DateTime * FairPriceLine
| LiquidityLineCreated of DateTime * LiquidityLine
| LiquidityLineReached of DateTime * LiquidityLine
member this.GetTimestamp () =
match this with
| ZoneStart (ts, _) -> ts
| ZoneEndExitHigh (ts, _) -> ts
| ZoneEndExitLow (ts, _) -> ts
| ZoneContraction (ts, _) -> ts
| ZoneExpansion (ts, _) -> ts
| FairPriceCrossHigh (ts, _) -> ts
| FairPriceCrossLow (ts, _) -> ts
| LiquidityLineCreated (ts, _) -> ts
| LiquidityLineReached (ts, _) -> ts
member this.GetInterval () =
match this with
| ZoneStart (_, x) -> x.Interval
| ZoneEndExitHigh (_, x) -> x.Interval
| ZoneEndExitLow (_, x) -> x.Interval
| ZoneContraction (_, x) -> x.Interval
| ZoneExpansion (_, x) -> x.Interval
| FairPriceCrossHigh (_, x) -> x.Interval
| FairPriceCrossLow (_, x) -> x.Interval
| LiquidityLineCreated (_, x) -> x.Interval
| LiquidityLineReached (_, x) -> x.Interval
我需要像这样提取所有 DU 类型中的许多公共字段;当然,他们也有很多不同的领域。
有没有更好的方法来提取公共字段? DateTime 与基础类型分开,但所有类型也有公共字段。
如何以更好的方式重写它?
正如 Fyodor 所建议的,这可以重构为:
type AnalysisEventType =
| ZoneStart of ConsolidationZone
| ZoneEndExitHigh of ConsolidationZone
| ZoneEndExitLow of ConsolidationZone
| ZoneContraction of ConsolidationZone
| ZoneExpansion of ConsolidationZone
| FairPriceCrossHigh of FairPriceLine
| FairPriceCrossLow of FairPriceLine
| LiquidityLineCreated of LiquidityLine
| LiquidityLineReached of LiquidityLine
type AnalysisEvent =
{
EventType : AnalysisEventType
Timestamp : DateTime
}
member this.GetTimestamp () = // you probably don't even need this any more
this.Timestamp
member this.GetInterval () =
match this.EventType with
| ZoneStart x
| ZoneEndExitHigh x
| ZoneEndExitLow x
| ZoneContraction x
| ZoneExpansion x -> x.Interval
| FairPriceCrossHigh x
| FairPriceCrossLow x -> x.Interval
| LiquidityLineCreated x
| LiquidityLineReached x -> x.Interval
如果你想进一步重构,你可以这样做:
type ConsolidationZoneEventType =
| Start
| EndExitHigh
| EndExitLow
| Contraction
| Expansion
type FairPriceEventType =
| CrossHigh
| CrossLow
type LiquidityLineEventType =
| Created
| Reached
type AnalysisEventType =
| ConsolidationZoneEventType of ConsolidationZoneEventType * ConsolidationZone
| FairPriceEventType of FairPriceEventType * FairPriceLine
| LiquidityLineEventType of LiquidityLineEventType * LiquidityLine
member this.GetInterval () =
match this with
| ConsolidationZoneEventType (_, x) -> x.Interval
| FairPriceEventType (_, x) -> x.Interval
| LiquidityLineEventType (_, x) -> x.Interval
type AnalysisEvent =
{
EventType : AnalysisEventType
Timestamp : DateTime
}
member this.GetTimestamp () =
this.Timestamp
member this.GetInterval () =
this.EventType.GetInterval ()
我建议按照 Brian 的建议进行操作并重构代码,以便您拥有 Timestamp
的记录,并使用事件详细信息单独区分并集。
但是,如果您真的想将您的表示保留为与重复项目的并集,您可以通过使用一种活动模式来稍微简化逻辑,该模式根据事件包含的其他信息识别不同类型的事件 - 所以所有 Zone
事件将被识别为一件事。为简单起见,这里是一个仅使用后两种事件类型的示例:
let (|FairPriceEvent|LiquidityEvent|) e =
match e with
| FairPriceCrossHigh(ts, l) | FairPriceCrossLow(ts, l) ->
FairPriceEvent(ts, l)
| LiquidityLineCreated(ts, l) | LiquidityLineReached (ts, l) ->
LiquidityEvent(ts, l)
现在你可以只考虑三种(在我的例子中是两种)情况来编写逻辑:
let getTimeStamp e =
match e with
| FairPriceEvent(ts, _)
| LiquidityEvent(ts, _) -> ts
let getInterval e =
match e with
| FairPriceEvent(_, l)
| LiquidityEvent(_, l) -> l.Interval
我这里有一些非常难看的代码:
type AnalysisEvent =
| ZoneStart of DateTime * ConsolidationZone
| ZoneEndExitHigh of DateTime * ConsolidationZone
| ZoneEndExitLow of DateTime * ConsolidationZone
| ZoneContraction of DateTime * ConsolidationZone
| ZoneExpansion of DateTime * ConsolidationZone
| FairPriceCrossHigh of DateTime * FairPriceLine
| FairPriceCrossLow of DateTime * FairPriceLine
| LiquidityLineCreated of DateTime * LiquidityLine
| LiquidityLineReached of DateTime * LiquidityLine
member this.GetTimestamp () =
match this with
| ZoneStart (ts, _) -> ts
| ZoneEndExitHigh (ts, _) -> ts
| ZoneEndExitLow (ts, _) -> ts
| ZoneContraction (ts, _) -> ts
| ZoneExpansion (ts, _) -> ts
| FairPriceCrossHigh (ts, _) -> ts
| FairPriceCrossLow (ts, _) -> ts
| LiquidityLineCreated (ts, _) -> ts
| LiquidityLineReached (ts, _) -> ts
member this.GetInterval () =
match this with
| ZoneStart (_, x) -> x.Interval
| ZoneEndExitHigh (_, x) -> x.Interval
| ZoneEndExitLow (_, x) -> x.Interval
| ZoneContraction (_, x) -> x.Interval
| ZoneExpansion (_, x) -> x.Interval
| FairPriceCrossHigh (_, x) -> x.Interval
| FairPriceCrossLow (_, x) -> x.Interval
| LiquidityLineCreated (_, x) -> x.Interval
| LiquidityLineReached (_, x) -> x.Interval
我需要像这样提取所有 DU 类型中的许多公共字段;当然,他们也有很多不同的领域。
有没有更好的方法来提取公共字段? DateTime 与基础类型分开,但所有类型也有公共字段。
如何以更好的方式重写它?
正如 Fyodor 所建议的,这可以重构为:
type AnalysisEventType =
| ZoneStart of ConsolidationZone
| ZoneEndExitHigh of ConsolidationZone
| ZoneEndExitLow of ConsolidationZone
| ZoneContraction of ConsolidationZone
| ZoneExpansion of ConsolidationZone
| FairPriceCrossHigh of FairPriceLine
| FairPriceCrossLow of FairPriceLine
| LiquidityLineCreated of LiquidityLine
| LiquidityLineReached of LiquidityLine
type AnalysisEvent =
{
EventType : AnalysisEventType
Timestamp : DateTime
}
member this.GetTimestamp () = // you probably don't even need this any more
this.Timestamp
member this.GetInterval () =
match this.EventType with
| ZoneStart x
| ZoneEndExitHigh x
| ZoneEndExitLow x
| ZoneContraction x
| ZoneExpansion x -> x.Interval
| FairPriceCrossHigh x
| FairPriceCrossLow x -> x.Interval
| LiquidityLineCreated x
| LiquidityLineReached x -> x.Interval
如果你想进一步重构,你可以这样做:
type ConsolidationZoneEventType =
| Start
| EndExitHigh
| EndExitLow
| Contraction
| Expansion
type FairPriceEventType =
| CrossHigh
| CrossLow
type LiquidityLineEventType =
| Created
| Reached
type AnalysisEventType =
| ConsolidationZoneEventType of ConsolidationZoneEventType * ConsolidationZone
| FairPriceEventType of FairPriceEventType * FairPriceLine
| LiquidityLineEventType of LiquidityLineEventType * LiquidityLine
member this.GetInterval () =
match this with
| ConsolidationZoneEventType (_, x) -> x.Interval
| FairPriceEventType (_, x) -> x.Interval
| LiquidityLineEventType (_, x) -> x.Interval
type AnalysisEvent =
{
EventType : AnalysisEventType
Timestamp : DateTime
}
member this.GetTimestamp () =
this.Timestamp
member this.GetInterval () =
this.EventType.GetInterval ()
我建议按照 Brian 的建议进行操作并重构代码,以便您拥有 Timestamp
的记录,并使用事件详细信息单独区分并集。
但是,如果您真的想将您的表示保留为与重复项目的并集,您可以通过使用一种活动模式来稍微简化逻辑,该模式根据事件包含的其他信息识别不同类型的事件 - 所以所有 Zone
事件将被识别为一件事。为简单起见,这里是一个仅使用后两种事件类型的示例:
let (|FairPriceEvent|LiquidityEvent|) e =
match e with
| FairPriceCrossHigh(ts, l) | FairPriceCrossLow(ts, l) ->
FairPriceEvent(ts, l)
| LiquidityLineCreated(ts, l) | LiquidityLineReached (ts, l) ->
LiquidityEvent(ts, l)
现在你可以只考虑三种(在我的例子中是两种)情况来编写逻辑:
let getTimeStamp e =
match e with
| FairPriceEvent(ts, _)
| LiquidityEvent(ts, _) -> ts
let getInterval e =
match e with
| FairPriceEvent(_, l)
| LiquidityEvent(_, l) -> l.Interval