F#
昨日の件、Seq.pairwiseのコードをちょっと変更した関数を作ってもいいかもしれない。 pairwiseを変形したコード たとえばpeekという関数にする。シグネチャは val peek : seq -> seq。module Seq = let peek (source:seq<'T>) = seq { use ie = source.GetE…
リストの場合は再帰関数とパターンマッチングでできるんですが、シーケンスだとそうもいかず冗長になっちゃうなぁと思った。 リスト [<Test>] let ``detect last element of list`` () = let rec loop = function | [] -> () | [x] -> printfn "last %d" x | h :: </test>…
C#で作っていたのですが、F#が面白いのでF#で作り直すことにしました。Somaは、SQLやSQLに埋め込まれた簡易的な式言語をパースしたりするんですが、C#では正規表現をつかって何とかしてました。F#ではこのあたりの処理にF# PowerPackのfsyaccとfslexを使える…
Enumerable.Skipに相当するものがF#にはないんですね。Seq.skipは件数足りないときに例外なげます。Enumerable.Skip vs Seq.skipに対策方法が書いてあります。Seqという名前で自分のモジュールを作って、そこに関数おくのがわかりやすいかも。あたかも、F#の…
判別共用体とアクティブパターンも使いました。結構すっきり書けました。type FizzBuzz = | Str of string | Num of int[<Test>] let ``fizzbuzz with Seq.init and Seq.zip``() = let (|Incr|) n = n + 1 let create num s = Seq.init 100 (function Incr(n) -> i</test>…
思いつきで試してみたらできました。一度、Seq.groupByで1から100までの数値をグループ分けし、その後でキーと値を入れ替えるような処理をSec.collectで行って、数値でソートして、文字でグループされていたかどうかをパターンマッチングでみて、最後に出力…
無理やりな感が満載ですが。Seq.chooseで1から100までの数値をシーケンスのグループに分け、そのあとでSeq.existsでそれぞれのグループへの存在チェックをしています。[<Test>] let ``fizzbuzz with Seq.choose``() = let (|Fizz|_|) n = if n % 3 = 0 then Some()</test>…
F# User Group - Japanにあるコードを参考にさせてもらいました。 https://groups.google.com/group/fsug-jp/browse_thread/thread/ca53aeedabe0a5c4?hl=ja type FizzBuzz = | Str of string | Num of int[<Test>] let ``fizzbuzz with function composition``() =</test>…
先日のアクティブパターンでFizzBuzzで書いた内容は今思うとあまりアクティブパターンのよさを引き出していないかも。 もっとアクティブパターンぽい方法を思いつきました。[<Test>] let ``fizzbuzz with partial active pattern``() = let (|Fizz|_|) n = if n % </test>…
FizzBuzzの条件を判定する処理をばらばらのラムダ式にしてみました。 一度数値を判別共用体でラップしシーケンスにとります。後続のシーケンスでは、FizzBuzzの条件に合致したら値を置き換え、条件に合致しない場合や、すでにFizzBuzzしている場合はそのまま…
商を求めずに(%を使わないで)FizzBuzzできました。[<Test>] let ``fizzbuzz with Seq.unfold and Seq.zip3``() = let unfold num value = 1 |> Seq.unfold (fun n -> if num = n then Some(Some(value), 1) else Some(None, n + 1)) let nums = seq { for i in 1</test>…
これも商を求めないでFizzBuzz。Seq.scanを使ってみたかった。[<Test>] let ``fizzbuzz with Seq.scan``() = let fizzbuzz (f, b, value) n = let f', b' = f + 1, b + 1 match f, b with | 3, 5 -> (1 , 1 , "fizzbuzz") | 3, _ -> (1 , b', "fizz") | _, 5 -> (f</test>…
こんなO/Rマッパーがあったらどうだろう。[<Test>] let ``test`` () = let name = "jhon" let salary = 2000 let persons = query<Person> <@ let name = name in let salary = salary in " select * from person where name = /*name*/'a' and salary > /*salary*/0 " @> </person></test>…
アクティブパターンを使いこせるとかっこいいですよね。アクティブパターンでFizzBuzzは目新しい話ではなさそうですが、やってみました。 アクティブパターンを使わない例。 まずは普通に。fizzbuzz関数の中で条件分岐してます。[<Test>] let ``fizzbuzz without A</test>…
簡単に書けると楽しい。[<Test>] let ``reverse string`` () = let x = "abcdef" Assert.AreEqual("fedcba", x |> Array.ofSeq |> Array.rev |> String.Concat) 追記 サロゲートペアのことを考えないといけない。なるほど。 http://stackoverflow.com/questions/45</test>…
6.4.8 Member Constraint Invocation Expressionsという機能があって、ダックタイピングできるようです。F#でDuck Typingも参考になりました。マニュアルに書いてあるのを少しだけ変更。パラメータをもつメソッドも呼び出してみました。type Duck() = member…
かるくぐぐったところ、計算式を使ったFizzBuzzは見当たらなかったのでやってみました。type FizzBuzzBuilder() = member x.For(elements, forBody) = for e in elements do forBody e member x.Yield(i) = if i % 3 = 0 && i % 5 = 0 then printfn "Fizz Bu…
Seq.collectやSelectManyが理解しづらいので簡単なコードで整理してみました。 F# [<Test>] let ``cartesian product`` () = let numbers = seq {for i in 1 .. 3 -> i} let results = numbers |> Seq.collect (fun n1 -> numbers |> Seq.map (fun n2 -> n1, n2)) </test>…
動かしてみてよくわかりました。 シーケンス let seq1 = seq { for i in 1..3 do printfn "generating... %d" i yield i }let seq2 = seq1 |> Seq.map (fun x -> printfn "1st map %d" x ; x) |> Seq.map (fun x -> printfn "2nd map %d" x;x)let seq3 = Seq…
コード引用符を使うことで式を取得できます。C#のExpression>で受けるのと同じようなものでしょうか。 なんかおもしろいことができそうな気がします。Personレコードをのプロパティを指定してその名前を取得するコードを書いてみました。open Microsoft.FSha…
レコード型、毎回すべてのプロパティを設定するのは大変なのでデフォルト値を設定したプロトタイプのインスタンスをあらかじめ作っておくといいかもしれない。 毎回 with を使って作成することになるので型が明示されてわかりやすいというおまけもあります。…
F#の中でわかりやすく、それでいてクールな機能が測量単位というものです。メートルとかキログラムとか好きな単位を作成して指定できます。open NUnit.Framework[<Measure>] type m[<Measure>] type kglet calculateBMI (height : float<m>) (weight : float<kg>) = weight / (height </kg></m></measure></measure>…
F#には、いろいろと興味深い機能がありますが、オブジェクト式もそのひとつ。open NUnit.Frameworktype IGreeing = abstract Greet : string -> string[<Test>] let ``test Object Expression``() = let greeting = { new IGreeing with member this.Greet(name) =</test>…
Expert F# 2.0 (Expert's Voice in F#)作者: Don Syme,Adam Granicz,Antonio Cisternino出版社/メーカー: Apress発売日: 2010/06/01メディア: ペーパーバック購入: 1人 クリック: 35回この商品を含むブログ (2件) を見るこの本を読んでいます。 その中で関数…
NaturalSpecのScenarioという属性、NUnitのTestAttributeを継承しているだけなことに気づきました。ということは、Resharperはクラスに指定するTestFixtureAttributeがなくてもメソッドに指定するTestAttributeだけがあればテストと認識するんですね。MSTest…
C#にはあるのにF#にはなぜかテストプロジェクトがないんですよね。 でもMicrosoft.VisualStudio.QualityTools.UnitTestFramework.dllに参照通せば、一応使えるみたいです。ただResharper使ってないとうまく認識させられないかも。F# Libraryを作って、Micros…
NaturalSpecでも動きました。これもResharperを使っていると簡単。 NaturalSpec.dllとnunit.framework.dllに参照を通す ソリューションかプロジェクトを選んで「Run Unit Tests」 次のようなテストコードが書けます。かっこいい!んだけどどう動いているのか…
パターンマッチグというものを使うとVisitorパターン相当のことが簡単に書けるということを聞いて、関数型プログラミングに興味を持ち始めました。というわけで最近F#をさわったりしています。 で、パターンマッチというものがどういったものかわかってきた…