2016年1月31日日曜日

プログラミングF#入門

P257 10章計算式が参考になった。
 コンピューテンション式という言い方が、今は一般的らしいが、ネット等でいろいろ調べてみたが、いまいちすっきりしなかった。この書籍も、最初1回読んだだけでは理解出来なかったが、再度挑戦してみたら、だいぶ意味がつかみやすくなった。やはり、書籍を読むこととネットでいろいろな具体例に触れることの両方が大切だとあらためて感じる。
 通常のコーディングだと、複雑になりやすいパターンを、独自の定義により簡潔に表すことができるようになるようだ。最初の設計は大変だろうが、いったんできてしまえば、コーディングをわかりやすく簡潔にできるということのようだ。

2016年1月30日土曜日

実践F#関数型プログラミング入門 P377

リスト10-7 再帰を利用してwhileループを作る
 let rec myWhile(condition,behavior,arg)=
 if condition(arg) then myWhile(condition,arg,behavior(arg))
 else arg;;
と本の通りやってみたが、エラー
そこで、
let rec myWhile(condition,behavior,arg) =
   if condition(arg) then myWhile(condition,behavior,behavior(arg))
   else arg;;
としたら動いた。
ただ、正誤表にないので、ひょっとして自分の基本的間違いなのか?よくかわからない。

2016年1月28日木曜日

実戦F# 関数型プログラミング P295

8.15.3 パラメタライズド アクティブパターン

リスト 8-70 を少し変えて、いろいろ試してみた。
let (|Mul|_|) m n = if n%m=0 then Some(n/m) else None;;

let fizzbuzz3 = function
    | Mul 15 nm -> printfn("FizzBuzz  15で割ると%d") nm
    | Mul 3 nm -> printfn("Fizz 3で割ると%d") nm
    | Mul 5 nm -> printfn("Buzz 5で割ると%d") nm
    | n -> printfn("%d") n;;

fizzbuzz3 30;;
FizzBuzz 15で割ると2

nが入力となるようだ。nmのところが、Someの中身になるようだ。

つぎに、入力を表示するためにつぎのようにしてみた。
let fizzbuzz2 input =
 match input with
    | Mul 15 nm -> printfn("%d is FizzBuzz") input
    | Mul 3 nm -> printfn("%d is Fizz") input
    | Mul 5 nm -> printfn("%d is Buzz") input
    | input -> printfn("%d") input;;

fizzbuzz2 3;;
3 is Fizz

いずれにしても、
let (|Mul|_|) m n   ①
では、引数の最後のnが入力と考え、let (|Mul|_|) mまでがカリー化した?関数とみなしているようだ。
そして、Mul 15 nm ②
のMul 15にinputや入力を適用し、結果がnmに返り値となって表れる。ということのようだ。入力と返り値が、①でも②でも最後の項だけれど、①では入力 ②までは出力 となっているところが まぎらわしい。

アクティブパターンは、F#独自の機能のようだけれど、うまく活用するとプログラムが
簡潔になるらしい。書籍を読むだけでなく、実際に、いろいろ試してみたほうが理解しやすいようだ。

2016年1月23日土曜日

SQLのLEFT JOINの活用

 グループウエアで、未読管理をしていたが、既読の場合にログにとして記録していく方式をとっていたため、時間がたつにつれ、どうしても反応が遅くなることに気がついた。
 EXISTSでサブクエリなど使うことなど検討したが、どうやらもっといい方法があることを、たまたまネット上で見つける。
 http://kkoudev.github.io/blog/2013/09/14/sql/
上記のサイトを参考にさせていただきました。わかりやすく説明されています。
 実際LEFT JOINで、いろいろ検索条件をしぼってやってみたところ、レスポンスが劇的に改善しました。

2016年1月3日日曜日

Vb.netからF#を呼び出してみる

F#を少し使ってみた。関数型言語に共通するのは、副作用の多いGUIが使いにくいところらしい。(F#でイベントを駆使すれば、いろいろ便利ではあるようだけど?)妥協案としてVB.netでGUI(View)部分を作って、副作用なしのロジック部分はF#を使うというのはどうだろうか。
http://ameblo.jp/ns-programming-memo/entry-11241535796.html
を参考にさせった。C#でも、VBでも、可能。vs2015で試した。

①Vb.netで、プロジェクトを作成。
②ソリューションエクスプローラで、新しいプロジェクトとして、F#のライブラリを選択
③Library1.fsで
 module Modulex
 let x a b = a*b;;
④VBのプロジェクトの参照で、参照の追加で、同じソリューションのフォルダにできている
Library1を追加
⑤vb.netでボタンを貼り付けて
 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MsgBox(Modulex.x(2, 3).ToString)
    End Sub
などとしてみたら、うまく動作することが確認できた。

**************
関数であれば
namespace Library1
open System
 module FSLib =
  let fsFunc=new Func<string,string>(fun s -> s+s)
がF#側にあれば、C#側では
 listBox1.Items.Add(Library1.FSLib.fsFunc("test"));
のように呼び出すこともできるようだ。
ただし、F#のライブラリはその都度、コンパイルしないと反映しないようだ。
**************
リストであれば
namespace Library1
open System
open System.Collections.Generic
module FSLib =
  let  Avg( array : List<float>) =
   let list = List.ofSeq(array)
   List.average list
をF#側とすれば、C#側では
List<double> myInts = new List<double> { 5, 6, 7.5 };
            double avg = Library1.FSLib.Avg(myInts);
            textBox2.Text = avg.ToString() ;
のような感じである。
ちょっとした、変換は必須のようである。
*****************
配列などは F#で
 let  text= File.OpenText( @"c:\test.csv").ReadToEnd().Split([|','|])
で取得した配列を
 textBox2.Text = FSLib.text[0];
のようにC#に渡すこともできるようだ。

let xx = [1..3] |> List.toArray
 let x2= [1..3]
というF#により
  textBox2.Text = FSLib.xx[0].ToString() ;や
  textBox2.Text = FSLib.x2[1].ToString();なども可能なようだ