F#类型和循环

Uzi*_*iel 5 f# types loops

我正在研究一个创建一副牌的F#教程.列出了类型,但我无法理解如何遍历类型以创建完整套牌的地图.我期待做类似的事情

Foreach rank in ranks
   Foreach suit in suits
       somehow combine the two
   next suit
next rank
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?以下是创建的类型.

我想如果我把它们从类型更改为列表它们可以合并,对吧?那么,类型有什么意义呢?

type suits=
    |Spade=1
    |Heart=2
    |Club=3
    |Diamond=4

type ranks=
    |ValCard of int
    |Jack 
    |Queen
    |King

type deck= Deck of ranks * suits
Run Code Online (Sandbox Code Playgroud)

Joh*_*mer 5

另一种使用区分联合的方法,它使用F#的语法比enum更好地网格化

type suit=
    |Spade
    |Heart
    |Club
    |Diamond
    static member all = [Spade;Heart;Club;Diamond]

type rank=
    |ValCard of int
    |Jack 
    |Queen
    |King
    static member all =([1..10]|> List.map (ValCard)) @ [Jack;Queen;King]

type card = |Card of rank * suit

let all_cards = suit.All |> List.collect (fun s -> rank.all |> List.map (fun r -> Card(r,s))
Run Code Online (Sandbox Code Playgroud)

然后你可以做一些整齐的模式匹配

all_cards 
|> List.iter (fun c ->
    match c with
    |Card(King,Spade) -> ...
    |Card(King,_) -> ...
    |Card(_) -> ...
Run Code Online (Sandbox Code Playgroud)

你甚至可以定义一些活动模式来获得红色/黑色卡片.


pad*_*pad 4

枚举是表示卡片的不错选择。您可以免费比较花色和等级,并轻松地将枚举从/转换为int

type suit =
    | Spade = 1
    | Heart = 2
    | Club = 3
    | Diamond = 4

type rank = 
    | Ace = 1 | Two = 2 | Three = 3 | Four = 4 | Five = 5 | Six = 6 | Seven = 7 
    | Eight = 8 | Nine = 9 | Ten = 10 | Jack = 11 | Queen = 12 | King = 13

/// 'Card' is a type which represents a particular card     
type Card = Card of rank * suit

/// 'deck' is a list consisting of all cards in a full deck
let deck = [ for r in 1..13 do
               for s in 1..4 do
                 yield Card(enum<rank> r, enum<suit> s) ]
Run Code Online (Sandbox Code Playgroud)

如果您选择受歧视的联合,则必须手动创建所有suits 和所有ranks 的列表。优点是 DU 的模式匹配比枚举更好。

type suit =
    | Spade
    | Heart
    | Club
    | Diamond

type rank = | Ace | Two | Three | Four | Five | Six | Seven 
            | Eight | Nine | Ten | Jack | Queen | King

type Card = Card of rank * suit

let private suits = [Spade; Heart; Club; Diamond]
let private ranks = [Ace; Two; Three; Four; Five; Six; Seven; 
                     Eight; Nine; Ten; Jack; Queen; King]

let deck = [ for rank in ranks do
               for suit in suits do
                 yield Card(rank, suit) ]
Run Code Online (Sandbox Code Playgroud)

  • DU 还提供“免费”比较(根据案例顺序)。 (2认同)