在使用警卫管理模式匹配时,抛出异常的替代方法是什么?

时间:2016-04-09 12:50:12

标签: f#

在使用警卫管理模式匹配时,抛出异常的替代方法是什么?

[<Literal>]
let Objective = 33

let (|NotGame|IsGame|) p =
    match p with
    | LessThanGame v when v <  Objective -> NotGame v
    | Game         v when v >= Objective -> IsGame  v

警告:

  

此表达式上的不完整模式匹配

我不希望编译器提出任何投诉。

因此,我不想做的是:

let (|NotGame|IsGame|) p =
    match p with
    | LessThanGame v when v <  Objective -> NotGame v
    | Game         v when v >= Objective -> IsGame  v
    | _ -> failwith "idk..."

我宁愿做的是:

let (|NotGame|IsGame|) p =
    match p with
    | LessThanGame v when v <  Objective -> NotGame v
    | Game         v when v >= Objective -> IsGame  v
    | _ v                                -> IsGame  v

整个代码在这里:

// ***********
// Game of 33 
// ************************************************************
(*Types*)
// ************************************************************
type Player = 
    | Player1
    | Player2

type Shot = 
     | TwoPointer
     | ThreePointer
     | FoulShot
     | TwoFoulShots
     | ThreeFoulShots

type PlayerScore = {Player:Player; Points:Points}

and Points = 
    | LessThanGame of int
    | Game of int

type Posession = Posession of Player

[<Literal>]
let Objective = 33

// ************************************************************
(*Active Patterns*)
// ************************************************************
let (|NotGame|IsGame|) = function
    | LessThanGame v when v <  Objective -> NotGame v
    | Game         v when v >= Objective -> IsGame  v
    | _ -> failwith "idk..."

// ************************************************************
(*Functions*)
// ************************************************************
let makeShot shot (shooter, defender) =

    let ballHandler = shooter.Player
    let points = shooter.Points

    let shotValue = match shot with
                    | TwoPointer   | TwoFoulShots   -> 2
                    | ThreePointer | ThreeFoulShots -> 3
                    | FoulShot                      -> 1

    match points with 
    | NotGame p ->  if p + shotValue < Objective then
                         { Player=ballHandler; Points=LessThanGame (p + shotValue) }, defender
                    else { Player=ballHandler; Points=Game         (p + shotValue) }, defender

    | IsGame  p -> { Player=ballHandler; Points=Game p }, defender

let startGame = 

    let player1Score = { Player=Player1; Points=LessThanGame 0 }
    let player2Score = { Player=Player2; Points=LessThanGame 0 }

    (player1Score, player2Score)

// ************************************************************
(*Client*)
// ************************************************************
let player1Score, player2Score = startGame

let player1, player2 = (player1Score, player2Score) |> makeShot TwoPointer
let shooter, defender = player2, player1

let final = (shooter, defender) |> makeShot ThreePointer
                                |> makeShot FoulShot

                                |> makeShot ThreePointer
                                |> makeShot TwoFoulShots

                                |> makeShot ThreePointer
                                |> makeShot ThreeFoulShots

                                |> makeShot ThreePointer
                                |> makeShot ThreePointer
                                |> makeShot ThreePointer
                                |> makeShot ThreePointer
                                |> makeShot ThreePointer

解决:

正如Guy Coder建议的那样,我使用if / else条件作为替代。因此,这消除了我抛出异常的需要。

// ************************************************************
(*Types*)
// ************************************************************
type Player = | Player1 | Player2

type Shot = 
     | TwoPointer| ThreePointer
     | FoulShot  | TwoFoulShots | ThreeFoulShots

type PlayerScore = {Player:Player; Game:Game}

and Game = 
    | Underway of int
    | AlmostGame of int
    | GameTime of int

[<Literal>]
let Objective = 33

[<Literal>]
let MaxFoulShots = 3

let (|Underway|AlmostGame|Game|) (score,shot) =

    let shotValue = match shot with
                    | FoulShot                      -> 1
                    | TwoPointer   | TwoFoulShots   -> 2
                    | ThreePointer | ThreeFoulShots -> 3

    match score, shotValue with
    | Underway   s,v -> if (s + v) <= (Objective - MaxFoulShots)
                        then Underway   (s + v)
                        else AlmostGame (s + v)

    | AlmostGame s,v -> if ( (s+v) < Objective )
                        then AlmostGame (s + v)
                        else Game Objective

    | GameTime   s,v -> Game s

// ************************************************************
(*Functions*)
// ************************************************************
let makeShot shot (shooter, defender) =

    match (shooter.Game, shot) with
    | Underway p   -> { shooter with Game=Underway p }, defender
    | AlmostGame p -> { shooter with Game=AlmostGame p }, defender
    | Game p       -> { shooter with Game=GameTime p }, defender

let startGame = 

    let player1Score = { Player=Player1; Game=Underway 0 }
    let player2Score = { Player=Player2; Game=Underway 0 }

    (player1Score, player2Score)

// ************************************************************
(*Client*)
// ************************************************************
let player1Score, player2Score = startGame

let player1, player2 = (player1Score, player2Score) |> makeShot TwoPointer
let shooter, defender = player2, player1

let final = (shooter, defender) |> makeShot ThreePointer
                                |> makeShot FoulShot

                                |> makeShot ThreePointer
                                |> makeShot TwoFoulShots

                                |> makeShot ThreePointer
                                |> makeShot ThreeFoulShots

                                |> makeShot ThreePointer
                                |> makeShot ThreePointer
                                |> makeShot ThreePointer
                                |> makeShot ThreePointer
                                |> makeShot ThreePointer

                                |> makeShot FoulShot
                                |> makeShot FoulShot
                                |> makeShot ThreeFoulShots

1 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题,您会尝试将输入分类为两个存储桶,条件为less than

如果是,则放弃模式匹配,只使用if语句。没有规则说功能必须使用模式匹配所有决策。