スポンサーサイト

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

F#入門中級編第5回(Computation Expression(5))

今回のお題は「Computation Expression(5)」です。
 
Computation Expressionには、よく使われる形のものがあるので、それを紹介します。
 
ではThe success/failure computation expressionを紹介します。
これは失敗の可能性もある、ある種の計算を続けていったときに、失敗したときに残りの計算をすることなしに結果を返すという場合に使います。
計算としては、二つの数の和でもし和が負になったら失敗として処理するものを取り上げることにします。
 
それでは例として計算結果を返す型を次のように定義します。
 
type Result = Success of int
              | Failure    
 
計算を定義します。
 
let trySum x y =
      let sum = x + y
      printfn "now add %d and %d" x y
      if sum >= 0 then
        Success(sum)
      else
        Failure
 
解釈クラスを定義します。
 
type SFbuilder () =
    
    member this.Bind (x, rest) =
        match x with
        |Success(u) -> rest u
        |Failure -> Failure
 
    member this.Return (x) = x
 

let sfb = new SFbuilder ()としておいて一つ関数を定義してみます。
 
let test00 a b  =
    sfb{ let! u = trySum a 1
         let! v = trySum b 1
         return trySum u v } 
         
実行してみます。
 
> test00 3 5;;
now add 3 and 1
now add 5 and 1
now add 4 and 6
val it : Result = Success 10
 
途中で失敗するように実行してみます。
 
> test00 -3 5;;
now add -3 and 1
val it : Result = Failure
 
実行結果から、最初の足し算をした時点で値を返して、あとは計算していないことがわかります。
 
一応念のために通常コードにtest00を直してみます。
 
let test00 a b  =
     sfb.Bind(trySum a 1,fun u ->           //#1
        sfb.Bind(trySum b 1,fun v ->        //#2
            sfb.Return(trySum u v)))        //#3
 
もう一度member.Bindを再掲します。
    member this.Bind (x, rest) =
        match x with
        |Success(u) -> rest u
        |Failure -> Failure
        
よって test00 3 5 とすると、1,2,3行のa,bはそれぞれ3,5を表すようになり、
まず#1のtrySum 3 5が評価されthis.BInd内のxがSuccess (8)となります、マッチ部に進んで、Success(u)とマッチするので、uを8として#2に進みます。あと同様の操作が続きます。
一方 test00 -3 5 とすると1,2,3行のa,bはそれぞれ-3,5を表すようになり、
まず#1のtrySum 3 5が評価されthis.BInd内のxがFailureとなります。この場合は、rest部分の計算は行われずに、Failureが返って終わりです。
マトリョーシカを開く前に、鍵に差し込む値をみて、その値がある条件を満たすときは、そこで処理をやめてしまうという流れです。
       
ということで、今回はsuccess/failure computation expressionを紹介しました。

スポンサーサイト

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

コメントの投稿

非公開コメント

typo

type Result の定義でのFailrue の綴りが違っている。
後のソースからも、Failure が正しい。

関数 trySum が定義されているが、
実際に例として使われているのは、mySum
多分、意味あいからは、mySum は、trySum の間違い。

sfb が、何の脈絡も無く使われているが、
出現前に、
let sfb = new SFbuilder ()
とか必要。(今までの説明ページからすると、省略できるとも思うけど)

今回は、いわゆるMayBeモナド ですね。
使う場面によっては便利につかえますね。

No title

御指摘ありがとうございます。訂正しました。
Maybeモナドの次はStateモナドをやっています。しかしthis.Forの内部でthis.Bindとthis.Zeroが呼び出されるのですが、どのような形で呼び出されるのかが分からず、悪戦苦闘しております。その途中でググっていると、以前 BLUEPIXY さんもブログで書かれていたBreakやContinueについてWorkFlowで実装した例がありました。参考までにURLを挙げておきます。http://tomasp.net/blog/imperative-ii-break.aspx
Haskellの本も2冊新刊が出ましたが、またまた積んどく状態におちいっています。

おおっ!

リンク先拝見しました。
こういうのが、本道ですよね!
一応こういうこともできると頭では理解していましたが、
自分でやるとなるとまた話は別ですよね。

クォーテーション

>どのような形で呼び出されるのか
例えば、クォート(<@ 式 @>)を使ってみたらどうですかね?
どういう風に実行形式として展開されるのかわかると思います。

例:
fsi を起動して、
> <@ seq { for i in 1..10 do yield i } @>;;
を実行してみると…

書込制限

たびたび「書込制限」に引っかかってコメントができませんでした。
どこか、引っかかったのかわからないため、
分割コメントしました。

以前のコメントで引っかかった時には多分コレだろうと検討ついたのですが、
今回最終的に削除した文章のどこが引っかかっていたのか、よく分からんです。

No title

>どのような形で呼び出されるのかが分からず
ttp://msdn.microsoft.com/ja-jp/library/dd233182(VS.100).aspx
は、見てるんですよね?

No title

アドバイスありがとうございます。そのぺージは見ているのですが、Combineの部分のCalled for sequencing in computation expressions.の意味合いが具体的にとれなくて、試行錯誤中です。
(書き込み制限は英数字フィルターなるものが、自動で設定されていたので、はずしました。)

No title

追記ですが、書き込み制限は英数字フィルターが原因ではなく、マイクロソフトのページのURLが関係しているようです。私も散々書き込み制限を受けたのですが、それを除くと書き込めました。(よく理由が分かりませんが)

マイクロソフトのページのURL

マイクロソフトのページのURLがダメ
どうやらそうみたいですね。
それで、http のh を除くことにしました。
携帯のブラウザからだと、不正アドレスになる(どうもカッコがイカンみたいな感じ)ので、そういう判定なのかもしれませんね。
プロフィール

T GYOUTEN

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

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

この人とブロともになる

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