6

カードのデッキを作成するF#チュートリアルに取り組んでいます。タイプはリストされていますが、タイプをループしてフルデッキのマップを作成する方法がわかりません。私は次のようなことをすることを期待していました

Foreach rank in ranks
   Foreach suit in suits
       somehow combine the two
   next suit
next rank

これを行う方法はありませんか?作成されるタイプは次のとおりです。

タイプからリストに変更すると、結合できると思いますよね?それで、タイプのポイントは何ですか?

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

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

type deck= Deck of ranks * suits
4

3 に答える 3

5

F#の構文を使用した列挙型よりも適切にメッシュ化される識別された共用体を使用する代替アプローチ

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))

次に、次のようなきちんとしたパターンマッチングを行うことができます

all_cards 
|> List.iter (fun c ->
    match c with
    |Card(King,Spade) -> ...
    |Card(King,_) -> ...
    |Card(_) -> ...

赤/黒のカードを取得するためにいくつかのアクティブなパターンを定義することもできます。

于 2012-12-12T07:37:21.697 に答える
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) ]

識別された共用体を使用する場合は、すべてsuitのおよびすべてのリストを手動で作成する必要がありますrank。利点は、列挙型よりも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) ]
于 2012-12-12T07:16:35.427 に答える
3

パッドの答えの補足として、反射を使用してデッキを生成することもできます。

type Union<'T> private () =
  static member val Cases = 
    FSharpType.GetUnionCases(typeof<'T>)
    |> Array.map (fun case -> FSharpValue.MakeUnion(case, null) :?> 'T)

let deck = 
  [ for rank in Union<rank>.Cases do
      for suit in Union<suit>.Cases do
        yield Card(rank, suit) ]
于 2012-12-12T18:19:55.187 に答える