使用 F# 类型的底层 primitive/collection

Use underlying primitive/collection of Type F#

目前正在学习 F# 并制作一个小 game/script 来尝试一些域建模等

我对 'elevated world' 的地图等有些熟悉,但看不出我如何在 atm 上做任何事情。

我的问题是我使用类型为游戏建模,现在我需要 access/use 作为类型创建的列表。但我无法以任何方式解构它。某些预期类型具有单个或多个反引号。这些是泛型吧?但是为什么会有这么多不同的?

如何deconstruct/use这些包装类型?

主要 - 查看打印的错误:

[<EntryPoint>]
let main argv =
    let game = TTTGame.CreateGame ["John";"CPU"]
    
    game.Players
        |> printfn "%A" 
    // Players [Player ("John", Symbol "X"); Player ("CPU", Symbol "O")]
        
    game.Players
        |> List.iter (fun c-> printfn $"%A{c}")
    // Expecting a 'Players -> 'a' 
    // but given a ''b list -> unit'    
    // The type 'Players' does not match the type ''a list'
    
    // No output, not sure why:   
    let deconstructP x =
        match x with
        | Players p when List.length p = 2 -> List.iter (fun v -> printfn $"%A{v}")
        | _ -> (fun _ -> printfn "Not a valid list of players")
    
    deconstructP game.Players
    
    0

'Domain' model/types:

module TicTacToe =
    
    type Symbol = Symbol of string
    type Tile = Tile of Symbol * int
    type Board  = Board of Tile list
    
    type Player = Player of string * Symbol
    type Players = Players of Player list
    
    type Game = {
        Players:Players
        Board:Board
    }
    
    type MakeMove = Game * Tile * Player -> Game

逻辑:

module TTTGame =
    open TicTacToe
    let private symbols = [Symbol"X";Symbol"O"]
    let private CreatePlayers (symbols:Symbol list) (playerNames:string list) =
       (playerNames , symbols)
       ||> List.map2 (fun x y -> Player(x,y))
       |> Players
       
    let private BuildPlayers = CreatePlayers symbols
    
    let private BuildBoard blank = Board([for xy in [1..10] do Tile(Symbol blank, xy)])
    
    let CreateGame players =
        BuildPlayers players
        |> fun p -> {
        Players=p
        Board=BuildBoard " "
    }

您可以通过模式匹配从 Player 实例中获取列表:

let players = Players [Player ("John", Symbol "X"); Player ("CPU", Symbol "O")]

let (Players playersList) = players

playersList
|> List.iter (fun c-> printfn $"%A{c}")

您也可以使用 OCaml 样式 let ... in ...:

let (Players playersList) = players in
  playersList
  |> List.iter (fun c-> printfn $"%A{c}")

但是,我认为 F# 的新手不太容易上手。