スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#入門第24回(Discriminated union(2))

今回のお題は「Discriminated union(2)」です。
 
まずは宿題の答えです。
(宿題)
上と同様にして、MyFloatOptionを定義してみてください。
その際、sumDispの代わりに、divDisp(割り算結果を表示する関数)を内部で定義してください。
ただし、値がない場合か、割ろうとする引数が0.0のときは、”割れません”と表示するようにしてください。
 
(答えの例)
 
type MyFloatOption =
    | MySomeFloat of float
    | MyNoneFloat  
    
    member this.divDisp  y =
        match this with
        | MySomeFloat (v)  when y <> 0.0 -> printfn "商は%fです" (v /y)
        | _                              -> printfn "割れません"  
 
上の答えに足し算の結果を表示する関数sumDispを付け加えてみます
 
type MyFloatOption =
    | MySomeFloat of float
    | MyNoneFloat  
    
    member this.divDisp  y =
        match this with
        | MySomeFloat (v)  when y <> 0.0 -> printfn "商は%fです" (v /y)
        | _                              -> printfn "割れません"  
    member this.sumDisp  y =
        match this with
        | MySomeFloat (v) -> printfn "和は%fです" (v + y)
        | MyNoneFloat     -> printfn "足せません" 
        
このようにしてmember部分をどんどん付け加えていくことができます。
 
それではDiscriminated unionのまとめとして、トランプのカードを型として表現してみましょう。ジョーカーは抜きにします。(これは、よくあるネタらしく、あちらこちらで見かけます。)
 
type CardSuit =
    | Spade
    | Club
    | Diamond
    | Heart
 
(これは対象を4通りに分けて、どちらも値を保持しない場合の例です。)
次に一枚一枚のカードを表す型として、Card型を定義します。
 
type Card =
    | Ace of CardSuit
    | King of CardSuit
    | Queen of CardSuit
    | Jack of CardSuit
    | NumCard of int * CardSuit
 
Ace,King,Queen,Jackは上で定義したCardSuit型を保持するものとして、それ以外のNumCardは数を表すintとスーツを表すCardSuitのタプルを保持するものとして定義されています。
 
例えば、識別子cにハートの8を束縛するには、次のようにします。
 
> let c = NumCard ( 8, Heart);;
val c : Card = NumCard (8,Heart)
 
それではブラックジャック用に、定義内でエースなら11、jack,queen,kingは10、その他のカードは数字通りの値を返す関数、valueBJを定義してみます。
 
type Card =
    | Ace of CardSuit
    | King of CardSuit
    | Queen of CardSuit
    | Jack of CardSuit
    | NumCard of int * CardSuit   
    member this.valueBJ =
        match this with
        | NumCard (x,_) -> x
        | Ace (_)       -> 11
        | _             -> 10
 
実行例 (先ほどの識別子cに対して)
 
> c.valueBJ;;
val it : int = 8
 
同様にスーツを返す関数、suitを追加しておきます。
 
type Card =
    | Ace of CardSuit
    | King of CardSuit
    | Queen of CardSuit
    | Jack of CardSuit
    | NumCard of int * CardSuit   
    member this.valueBJ =
        match this with
        | NumCard (x,_) -> x
        | Ace (_)       -> 11
        | _             -> 10
    member this.suit =
        match this with
        | Ace(c)       -> c
        | King (c)     -> c
        | Queen (c)    -> c
        | Jack (c)     -> c
        | NumCard(_,c) ->c
 
次に、二つのカード型の値を引数として、スーツが同じかどうかを返す。関数を定義してみます。型推論が効かないので、型注釈をつけています。
 
let isSameSuit (x : Card) (y : Card) =
        x.suit = y.suit        
 
実行例
 
> isSameSuit (Ace (Heart)) (Queen (Heart));;
val it : bool = true
 
> isSameSuit (Ace (Club)) (Queen (Heart));;
val it : bool = false
 
それでは、宿題です。Card型の値のリストを引数にして、和が21なら、"Black Jack",それより小さければ”20以下”、大きければ"オーバー”と表示する関数dispBJを定義してください。ただし、エースは常に11として数えることとします。
始まりは次のようになります。
let dispBJ (cLst : Card lst) =
 
 
またCard型の値のリストを引数にして、スペード、クラブ、ダイアモンド、ハートの枚数をint*int*int*intの型で、返す関数howManyEachSuitを定義してください。
始まりは次のようになります。
let howManyEachSuit (cLst : Card lst) =
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。