如何将两个大小写值表达式重构为一个



如何将两个大小写值表达式重构为一个

恐怕我仍然不清楚如何从这个逻辑中消除重复:

match redPiece with
| Checker checker -> checker |> set (checker |> attemptJump blackChecker yIncrementValue)
| King    king    -> king    |> set (king    |> attemptJump blackChecker yIncrementValue)

这个问题可能是重复的。然而,我仍然在努力重构这种类型的代码。

我该如何实现其中一个海报在我提供的链接上建议的包装器功能?

这是完整的功能:

let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =
    let yIncrementValue = -1
    let minY = 0
    let set position piece =
       match position with
       | pos when pos = piece   -> position , blackCheckers
       | _                      -> position , blackCheckers |> remove blackChecker
    match redPiece with
    | Checker checker -> checker |> set (checker |> attemptJump blackChecker yIncrementValue)
    | King    king    -> king    |> set (king    |> attemptJump blackChecker yIncrementValue)

整个域可以在这里找到:

(* Types *)
type BlackOption = NorthEast | NorthWest
type RedOption =   SouthEast | SouthWest
type KingOption = 
    | NorthEast 
    | NorthWest
    | SouthEast 
    | SouthWest
type Position =     { X:int; Y:int }
type BlackChecker = Position
type RedChecker =   Position
type BlackKing =    Position
type RedKing =      Position
type King = 
    | BlackKing of BlackKing
    | RedKing of RedKing
type RedPiece = 
    | Checker of RedChecker 
    | King of RedKing
type BlackPiece = 
    | BlackChecker of BlackChecker 
    | BlackKing of BlackKing
(* Private *)
let private remove item list = list |> List.filter (fun x -> x <> item)
let private setRowPosition y1 y2 y3 index =
    match index with 
    | x when x < 4 -> { X=x; Y=y1 }
    | x when x < 8 -> { X=x-4; Y=y2 }
    | _            -> { X=index-8; Y=y3 }
let private set (x, y) positions (position:Position) =
    match not (positions |> List.exists (fun pos -> pos = { X=x; Y=y })) with
    | true -> { X=x; Y=y }
    | false -> position
let private attemptJump target yDirection source =
    let updateX value = { X=target.X + value
                          Y=target.Y + yDirection }
    match source with
    | position when position.Y + yDirection = target.Y &&
                    position.X + 1 = target.X -> updateX 1
    | position when position.Y + yDirection = target.Y &&
                    position.X - 1 = target.X -> updateX -1
    | _ -> source
let private initializeBlack () =
    let setPosition index =
        index |> setRowPosition 7 6 5
    let blackCheckers = List.init 12 setPosition |> List.map (fun pos -> { X=pos.X; Y=pos.Y })
    blackCheckers
let private initializeRed () =
    let setPosition index =
        index |> setRowPosition 0 1 2
    let redCheckers =   List.init 12 setPosition |> List.map (fun pos -> { X=pos.X; Y=pos.Y })
    redCheckers
(* Exposed *)
let moveBlack direction positions (checker:BlackChecker) =
    let position = checker
    match direction with
    | BlackOption.NorthEast -> (positions, position) ||> set ((position.X + 1), (position.Y + 1 ))
    | BlackOption.NorthWest -> (positions, position) ||> set ((position.X - 1), (position.Y + 1 ))
let moveRed direction positions (checker:RedChecker) =
    let position = checker
    match direction with
    | RedOption.SouthEast -> (positions, position) ||> set ((position.X + 1), (position.Y - 1 ))
    | RedOption.SouthWest -> (positions, position) ||> set ((position.X - 1), (position.Y - 1 ))
let moveKing direction positions (king:King) =
    let position = match king with
                   | King.BlackKing bk -> bk
                   | King.RedKing   rk -> rk
    let result = match direction with
                 | NorthEast -> (positions, position) ||> set ((position.X + 1), (position.Y + 1 ))
                 | NorthWest -> (positions, position) ||> set ((position.X - 1), (position.Y + 1 ))
                 | SouthEast -> (positions, position) ||> set ((position.X + 1), (position.Y - 1 ))
                 | SouthWest -> (positions, position) ||> set ((position.X - 1), (position.Y - 1 ))
    match king with
    | King.BlackKing _ -> King.BlackKing result
    | King.RedKing   _ -> King.RedKing   result
let jumpRed ((redChecker:RedChecker), (redCheckers:RedChecker list)) (blackChecker:BlackChecker) =
    let yIncrementValue = 1
    let maxY = 7
    let position = blackChecker |> attemptJump redChecker yIncrementValue
    match position with
    | pos when pos = blackChecker -> BlackChecker position , redCheckers
    | pos when pos.Y = maxY       -> BlackKing    position , redCheckers |> remove redChecker
    | _                           -> BlackChecker position , redCheckers |> remove redChecker
let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =
    let yIncrementValue = -1
    let minY = 0
    let set position piece =
       match position with
       | pos when pos = piece   -> position , blackCheckers
       | _                      -> position , blackCheckers |> remove blackChecker
    match redPiece with
    | Checker checker -> checker |> set (checker |> attemptJump blackChecker yIncrementValue)
    | King    king    -> king    |> set (king    |> attemptJump blackChecker yIncrementValue)

我会像这样删除重复:

match redPiece with
    | Checker piece
    | King    piece    -> piece    |> set (piece    |> attemptJump blackChecker yIncrementValue)

最新更新