f# - 歧视联盟&让绑定(bind)?

标签 f# discriminated-union let-binding

为什么在有区别的联合中不允许使用 let 绑定(bind)?我认为这与在默认构造函数中执行的 let 绑定(bind)有关吗?

关于如何重写 AI_Choose 的任何建议。将不胜感激。我想将加权优先级与 AI 保持在一个元组中。我的想法是拥有 AI_Weighted_Priority继承 AI_Priority并覆盖选择。我不想处理不同长度的压缩列表(糟糕的做法 imo。)

open AI

type Condition =
    | Closest of float
    | Min
    | Max
    | Average
    member this.Select (aiListWeight : list<AI * float>) =
        match this with
        | Closest(x) -> 
            aiListWeight 
            |> List.minBy (fun (ai, priority) -> abs(x - priority))
        | Min -> aiListWeight |> List.minBy snd
        | Max -> aiListWeight |> List.maxBy snd
        | Average -> 
            let average = aiListWeight |> List.averageBy snd
            aiListWeight 
            |> List.minBy (fun (ai, priority) -> abs(average - priority))

type AI_Choose =
    | AI_Priority of list<AI> * Condition
    | AI_Weighted_Priority of list<AI * float> * Condition

    // I'm sad that I can't do this    
    let mutable chosen = Option<AI>.None

    member this.Choose() =
        match this with
        | AI_Priority(aiList, condition) -> 
            aiList 
            |> List.map (fun ai -> ai, ai.Priority())
            |> condition.Select
            |> fst
        | AI_Weighted_Priority(aiList, condition) -> 
            aiList 
            |> List.map (fun (ai, weight) -> ai, weight * ai.Priority())
            |> condition.Select
            |> fst

    member this.Chosen
        with get() = 
            if Option.isNone chosen then
                chosen <- Some(this.Choose())
            chosen.Value
        and set(x) =
            if Option.isSome chosen then
                chosen.Value.Stop()
            chosen <- Some(x)
            x.Start()

    interface AI with
        member this.Start() =
            this.Chosen.Start()
        member this.Stop() =
            this.Chosen.Stop()
        member this.Reset() =
            this.Chosen <- this.Choose()
        member this.Priority() =
            this.Chosen.Priority()
        member this.Update(gameTime) =
            this.Chosen.Update(gameTime)

最佳答案

对于任何感兴趣的人,我最终得出 AI_PriorityAI_Weighted_Priority来自抽象基类。

[<AbstractClass>]
type AI_Choose() =
    let mutable chosen = Option<AI>.None

    abstract member Choose : unit -> AI

    member this.Chosen
        with get() = 
            if Option.isNone chosen then
                chosen <- Some(this.Choose())
            chosen.Value
        and set(x) =
            if Option.isSome chosen then
                chosen.Value.Stop()
            chosen <- Some(x)
            x.Start()

    interface AI with
        member this.Start() =
            this.Chosen.Start()
        member this.Stop() =
            this.Chosen.Stop()
        member this.Reset() =
            this.Chosen <- this.Choose()
        member this.Priority() =
            this.Chosen.Priority()
        member this.Update(gameTime) =
            this.Chosen.Update(gameTime)

type AI_Priority(aiList : list<AI>, condition : Condition) =
    inherit AI_Choose()
    override this.Choose() =
        aiList 
        |> List.map (fun ai -> ai, ai.Priority())
        |> condition.Select
        |> fst

type AI_Weighted_Priority(aiList : list<AI * float>, condition : Condition) =
    inherit AI_Choose()
    override this.Choose() =
        aiList 
        |> List.map (fun (ai, weight) -> ai, weight * ai.Priority())
        |> condition.Select
        |> fst

关于f# - 歧视联盟&让绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1332299/

相关文章:

f# - 通过模式匹配比较 F# 区分的联合实例

silverlight - 使用 F# 创建 Silverlight 3 应用程序

F# - 我可以从函数返回一个可区分的联合吗

.net - F# 中的函数应用运算符 ($)?

typescript - 即使在使用类型保护检查之后也无法缩小对象属性的类型

f# - 如何在 F# 中正确实现属性?

f# - F# 标识符、模块、类型和成员名称中允许使用哪些字符?

list - F#::遍历列表然后再次返回

f# - List.map fsi 显示正常,但无法构建