スポンサーサイト

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

F#入門初級編第2回(Active Pattern (2))

今回のお題は「Active Pattern (2)」です。
 
(3)Multi-case Active Pattern
 
Mutlti-case Active Patternというのは、パターンマッチの際一枚かぶせる補助関数が、いくつかのカテゴリーのどれかを返すというパターンです。
分かりにくいと思うのでまずは一つ例を挙げます。
 
let (|Hot|Just|Cold|) x =
    if x > 42 then Hot
    elif x >38 then Just
    else Cold
 
let howYukagen t =
    match t with // #1
    |Hot -> printfn "熱いです"
    |Just ->printfn "ちょうどいい湯加減です"
    |Cold ->printfn "ぬるいです"
    
まず1の部分でマッチ候補を見てHot,Just,Coldがカテゴリーとされている関数を探し(この場合は関数(|Hot|Just|Cold|)が見つかる)、この関数をtに適用します。その結果とHot,Just,Coldを順にマッチさせてマッチしたところが処理されるという仕組みです。
 
このパターンで使う関数はつぎのような形となります。
 
let (|ident_1|ident_2|....|ident_n|) = expr
だだしidnet_?の先頭は大文字
返り値はident_1 .. ident_nの内どれか(だだし各カテゴリーには値を付加できる) 
 
だだし各カテゴリーには値を付加できる)の部分が目を引くと思います。説明のために次の例を見てください。
 
let (|Hot|Just|Cold|) x =
    if x > 42 then Hot (x - 42)    //#1
    elif x >38 then Just           //#2
    else Cold (38-x,"勘弁してよ。")//#3
 
let howYukagen t =
    match t with
    |Hot dif-> printfn "熱いです%d度下げてください。" dif //#4
    |Just ->printfn "ちょうどいい湯加減です"              
    |Cold (dif,str) ->printfn "%d度ぬるいです。%s" dif str
 
    
 
とりあえず実行してみます。
 
> howYukagen 45;;
熱いです3度下げてください。
val it : unit = ()
 
> howYukagen 40;;
ちょうどいい湯加減です
val it : unit = ()
 
> howYukagen 32;;
6度ぬるいです。勘弁してよ。
val it : unit = ()
 
 
例えばt=45に関数(|Hot|Just|Cold|)を適用するとHotに(45-42)すなわち3が付加されたものが返ります。
これは#4の部分でマッチし、difには3が束縛されます。
 
このように各カテゴリー別に異なる型の値を付加して返せるのがMulti-case Active Patternの強みです。
 
言い換えるとMulti-case Active Patternは引数に対して、Descriminated Unionの値を返す関数を一枚かぶせてマッチを試みるパターンです。
 
ちなみに上の関数(|Hot|Just|Cold|)の型を調べてみると、
val ( |Hot|Just|Cold| ) : int -> Choice<int,unit,(int * string)>
となっていて、ひそかに、Choiceヘルパー型というものが定義されて、これが使われています。
 
最後にアクティブパターンの結合を紹介します。
アクティブパターンではand,orを&,|が担当します。 
 
上の湯加減のアクティブパターン用の関数に加えて、洗濯が可能かどうかのパーシャル アクティブパターン用の関数を追加します。
 
let (|CanForWash|_|) x =
    if 10 < x && x < 40 then
        Some()
    else
        None
 
こうしておいて
let canTakeBathAndWash x =
    match x with
    | Just  & CanForWash
        -> true
    | _ -> false
 
と定義すると湯加減もよく、洗濯にも使える温度かどうかを調べることができます。
 
湯加減としてはだめ(つまり熱いか冷たい)だけど、洗濯には使える場合は次のような関数で調べることができます。
 
let onlyForWash x =
    match x with
    | ((Hot _)| Cold (_,_)) & CanForWash
        -> true
    | _ -> false

スポンサーサイト

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

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

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

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

この人とブロともになる

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