F#マスターへの道
http://w.atwiki.jp/fsharpmaster/
F#マスターへの道
ja
2013-12-17T00:32:03+09:00
1387207923
-
型から始めるプログラミング
https://w.atwiki.jp/fsharpmaster/pages/40.html
*型から始めるプログラミング
この記事は「[[F# Advent Calendar 2013>http://connpass.com/event/3935/]]」16日目の記事です。
**型に導かれて
静的な強い型を持った関数型プログラミングにある程度馴染んでくると、次第に「コンパイルを通ったものは大抵動く」という不思議な感覚を持つようになります。この感じは手続き型プログラミングしかやったことがない人にはなかなか伝わらないもので、そんな話をしても大体「そんなわけあるわけないwww」というような反応を受け、こちらもうまく伝えられずモゾモゾすることになりがちです。
もちろん「コンパイル通ればできてる」というのが正しくない、というのは分かりきったことなのですが、「コンパイルを通った時点で動いたものに何の問題もなかった」という事象の確率がかなり高いのもまた統計的なデータこそないものの皆様肌で感じているのではないかと思います。
こういう「コンパイル通ったと思ったら動いた」というプログラムは、僕の経験では「大がかりな型」を想定することからスタートすることで持たされることが多い気がします。
今回は課題として、CSVを読みこみいくつかのチェックと変換をして別のファイルに書きだすプログラムを書きながら、「大がかりな型」からプログラムを作っていく過程を見ていただきましょう。とはいっても最初なので小さめですが。
**作るもの
作ってみるプログラムの機能はこんなものです。
+ CSVから一行を読みこみ、カンマで区切って前後のダブルクォーテーションや空白を削除し、文字列の配列を作る
+ 配列の特定の項目について、
-空白ならば0とする
-特定の項目間で何らかの計算をする
-条件を満たしていない場合は例外を出す(本当はログを出した方がいいのですが、今回の主旨からはずれるので)
+結果として出来上がったデータをCSVとして保存する。
手続き型プログラミングでも普通に作れそうなものですが、ここはF#なりに、「大がかりな型」をベースにプログラミングをしていくことにします。
**ファイルの読み込みとCSV展開
F#では、行データのシーケンスとしてファイルを扱うことが一般的です。
let getC
2013-12-17T00:32:03+09:00
1387207923
-
コレクションまとめ
https://w.atwiki.jp/fsharpmaster/pages/39.html
|BGCOLOR(#DDDDFF):|CENTER:BGCOLOR(#DDDDFF):しくみ|CENTER:BGCOLOR(#DDDDFF):長所|CENTER:BGCOLOR(#DDDDFF):短所|
|BGCOLOR(#DDDDFF):リスト(List)|要素ごとに、次の要素がどこにあるかというポインタを持つ。|不変。長さが可変。データに順序性がある。|先頭から順にアクセスすることとしかできない。メモリ使用量は多め。|
|BGCOLOR(#DDDDFF):配列(Array)|連続したメモリ空間に順次格納する。|連続した領域に保存されるため、インデックス番号で高速にアクセス可能。|サイズ変更に大きな時間がかかる場合がある。|
|BGCOLOR(#DDDDFF):マップ(Map)|内部に用意された配列に、ハッシュ関数を使用してアクセスする。|不変。キーを利用して固定時間でのアクセスが可能。インデックスが連続する自然数である必要がない。|データに順序性が(表向きには)ない。要素数が少ない場合にはListを線形探索した方が早い場合がある。|
|BGCOLOR(#DDDDFF):集合(Set)|内部に用意された配列に、ハッシュ関数を使用してアクセスする。|不変。Mapに似ているが、特定のキーが集合に存在するかどうかだけを保持する。|左の目的に合致すれば、Mapよりもメモリ使用量は少ない。|
|BGCOLOR(#DDDDFF):シーケンス(Seq)|要素の並びをどこかに持っているわけではなく、「次の値を生成する関数」を値が要求されるたびに呼び出しているだけ。|無限集合を扱える。値を保持しているわけではないのでメモリを食わない。|シーケンシャルに取り出してもあまり早くない。|
2013-11-30T13:11:47+09:00
1385784707
-
ペンローズ・タイル
https://w.atwiki.jp/fsharpmaster/pages/38.html
*平面充填のもう一つの形 --ペンローズタイル--
平面充填といえばこの話を避けて通ることはできないでしょう。イギリスの物理学者、ロジャー・ペンローズが提示した、平面充填のパターンで、繰り返しに周期性を持たない非常にレアものです。
#ref(Penrose01.png)
調べてみると、ペンローズタイル作成のプログラムは[[lispで書かれたもの>http://antares.sci.fukuoka-u.ac.jp/wiliki/wiliki.cgi?%E3%83%9A%E3%83%B3%E3%83%AD%E3%83%BC%E3%82%BA%E3%82%BF%E3%82%A4%E3%83%AB%E3%82%92%E4%B8%A6%E3%81%B9%E3%82%8B]]がなかなかの出来で、これをF#に移植してみました。
module Penrose
open System
open System.Drawing
open System.Drawing.Imaging
let xm = 1024
let ym = 768
let gl = (1.0 + Math.Sqrt(5.0)) / 2.0 // 黄金比
let OutBitmap = new Bitmap(xm, ym, PixelFormat.Format24bppRgb)
let g = Graphics.FromImage(OutBitmap)
g.Clear(Color.White)
let rot_point (x1, y1) (x2, y2) r n =
let x = (x2 - x1) * n
let y = (y2 - y1) * n
let r = r * (-1.0) * Math.PI
(x * Math.Cos(r) - y * Math.Sin(r) + x1,
x * Math.Sin(r) + y * Math.Cos(r) + y1)
let center (x1, y1) (x2, y2) =
((x2 - x1) / 2.0 + x1, (y2 - y1) / 2.0 + y1)
let draw_poi
2013-06-26T10:28:53+09:00
1372210133
-
エッシャーの爬虫類
https://w.atwiki.jp/fsharpmaster/pages/36.html
*エッシャーの「爬虫類」 - 平面を敷き詰める -
先日、色々調べ物をしているうちに、英語のWikipediaで「[[壁紙の分類>http://en.wikipedia.org/wiki/Wallpaper_group]]」というのを見つけてしまいました。平面を埋め尽くせる図形は、ここに挙げた17パターンのいずれかに属するとのこと。ほう。
これを見ていて、「[[ゲーデル・エッシャー・バッハ>http://www.amazon.co.jp/%E3%82%B2%E3%83%BC%E3%83%87%E3%83%AB-%E3%82%A8%E3%83%83%E3%82%B7%E3%83%A3%E3%83%BC-%E3%83%90%E3%83%83%E3%83%8F%E2%80%95%E3%81%82%E3%82%8B%E3%81%84%E3%81%AF%E4%B8%8D%E6%80%9D%E8%AD%B0%E3%81%AE%E7%92%B0-%E3%83%80%E3%82%B0%E3%83%A9%E3%82%B9%E3%83%BBR%E3%83%BB%E3%83%9B%E3%83%95%E3%82%B9%E3%82%BF%E3%83%83%E3%82%BF%E3%83%BC/dp/4826900252]]」に育てられた感のある僕は、「それではあの図形がこの中のどれに属するのか」という疑問を持ったのです。あの図形とエッシャーの「[[爬虫類>http://www.google.co.jp/search?q=%E3%82%A8%E3%83%83%E3%82%B7%E3%83%A3%E3%83%BC+%E7%88%AC%E8%99%AB%E9%A1%9E&hl=ja&tbm=isch&tbo=u&source=univ&sa=X&ei=eawmUeG1BM3tmAX-soGACw&ved=0CDAQsAQ&biw=853&bih=470]]」です。
この幾何学模様に魅せられたのは中学校ぐらいの時でしたが、その体験が後になって大学の図書館で前述の本を手に取るきっかけになり、毎日図書館通いをした挙句大学も中退し、さらにいろいろあって今の僕があるのですから人生わかりません。とにかく当時中学生の僕は何時間もこのトカゲを見続けたにもかかわらず、その時はその構造を見抜くことができませ
2013-04-27T18:50:27+09:00
1367056227
-
イメージPDFファイルの処理
https://w.atwiki.jp/fsharpmaster/pages/35.html
*スキャナが出力したPDFを、出力デバイスに合わせて変換しよう
この記事は[[F# Advent Calender 2012>http://atnd.org/events/33927]]の11日目(10個目)の記事です。ひとつ前の記事は[[yukitos22さんのTypeProvider関連の丁寧な記事>http://d.hatena.ne.jp/yukitos22/20121209]]で、これを書き終わったら手を動かして試してみたいところです。
さて、主催者様の「実用的な」というお題を僕はそのまま字面通りとってしまい、「仕事以外に、F#で実用的なプログラムを書いたっけ・・・」などと回想した結果ひねり出したのがこのネタです。
いささか「実用」というよりは「オレ用」という感じもしなくはないのですが・・・
僕が富士通の名作ドキュメントスキャナS1500を購入したのは、ひとえにオライリーの「プログラミング F#」や技評の「実践F#関数型プログラミング入門」を持ち歩くのが辛かったからである、と言っていいほど僕の中でF#とS1500のつながりは実は深く、S1500でスキャンしたデータをSONY Readerで持ち歩くための変換プログラムがF#で書かれたこともまた必然と言っていいと思います。
&ref(pdfconv01.png)
そんなわけで、このプログラムは1年前に書いたもので、今回の記事のためにチョコチョコ直しましたが色々とアレなところがある点についてはご容赦ください。
ちなみにPDFの操作は独自実装といいたいところですが、残念ながらiTextSharpを使用しています。開発環境はVS2008です。まだVS2012買ってないんですすみません。
実行にはiTextSharpが必要なため、[[ここからダウンロード>http://sourceforge.jp/projects/sfnet_itextsharp/]]してください。最新の5.3.3で動作確認しています。
**機能と使い方
-指定したPDFファイル(S-1500が出力したもの)から、JPEGファイルを取り出して特定のディレクトリに保存する(上のテキストボックスに元PDFのパスを入れて「PDF解体」)。出力先は「c:\temp」下になります。
2013-02-24T03:30:54+09:00
1361644254
-
ひまわりっぽいの
https://w.atwiki.jp/fsharpmaster/pages/34.html
*黄金の花を愛でる - 素数夜曲より -
整数論の独学者用教科書「[[素数夜曲>http://www.amazon.co.jp/%E7%B4%A0%E6%95%B0%E5%A4%9C%E6%9B%B2-%E5%A5%B3%E7%8E%8B%E9%99%9B%E4%B8%8B%E3%81%AELISP-%E5%90%89%E7%94%B0-%E6%AD%A6/dp/4486019245/ref=pd_sim_sbs_b_1/375-9064155-0642861]]」がリニューアルされたので、コンテンツで遊んでみました。この本で取り上げられているプログラミング言語はSchemeなので、それをまぁF#に移植しただけとも言いますが....
詳しいことは本を買って読んでください。整数論の玉手箱をひっくり返したような本で、いわば「宝の山」です。
**ソース
// Himawari K. Katayama with Sosuu Yakyoku
open System
open System.Drawing
open System.Windows.Forms
let a = 1
let b = 13
let rational x y = Seq.unfold (fun n -> if n = 0 then None
else Some (n / y, (n % y) * 10)) x
let phi = (1. + sqrt(5.)) / 2.
let ang = (2. * Math.PI) / (1. + phi)
let size = 75.
let k x = (0.998 ** x) * 1.
let brushes = [|
Brushes.Black; Brushes.Brown;
Brushes.Red; Brushes.Orange;
Brushes.Yellow; Brushes.Green;
2012-06-29T20:32:33+09:00
1340969553
-
動的計画法
https://w.atwiki.jp/fsharpmaster/pages/33.html
*月謝3500円のそろばん塾で出たチャレンジ問題(動的計画法で)
[[この記事>http://www4.atwiki.jp/fsharpmaster/pages/32.html]]の続きです。
[[Arigataさんが書かれたエントリ>http://d.hatena.ne.jp/arigata3/20120519/1337439370]]をフムフムと呼んでいて、MSのソルバに興味を持ちつつ、そもそも「部分和問題」という言葉も「ナップザック問題」という言葉も知らなかった自分の不勉強に恥じ、ちゃんと勉強しないとなぁ・・・と考えているだけの日々を送っていたのですが、何の因果か「[[アルゴリズムを学ぼう>http://www.amazon.co.jp/%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%82%92%E5%AD%A6%E3%81%BC%E3%81%86-%E5%B7%9D%E4%B8%AD%E7%9C%9F%E8%80%B6/dp/404886128X]]」などという本が絶好のタイミングで出てしまい、この中にこの「ナップザック問題」の解説が乗っていたので、これを参考にF#で「動的計画法」を使った解法を試してみることにしました。
お題自体は前回の[[このエントリ>http://www4.atwiki.jp/fsharpmaster/pages/32.html]]と同じです。
**動的計画法
まず基礎知識として、このそろばん塾の問題は、「[[部分和問題>http://ja.wikipedia.org/wiki/%E9%83%A8%E5%88%86%E5%92%8C%E5%95%8F%E9%A1%8C]]」という有名なカテゴリに属する問題で、金額の部分が整数でない場合には「[[NP完全>http://ja.wikipedia.org/wiki/NP%E5%AE%8C%E5%85%A8]]」という、要素数が上がるにつれ幾何級数的に計算量が増えていく性質を持っているということです。
ただし、次のようないくつかの制限が許される場合は、劇的に計算量を減らすアルゴリズムが知られています。このアルゴリズムが今回のお題となっている「[[動的計画法(Dynamic Pr
2014-05-05T22:02:39+09:00
1399294959
-
月謝3500円のそろばんの問題
https://w.atwiki.jp/fsharpmaster/pages/32.html
*月謝3500円のそろばん塾で出たチャレンジ問題
「子供が通っているそろばん塾で、みんなで競う系の問題が出されたのを見ていると、ちょっとムズムズしてしまいVS2008を起動してしまった、の巻き」です・・・大人気ない。
**お題
|商品|金額|
|プロ野球|19373円|
|ディズニーランド|20453円|
|回転ずし|15906円|
|ピアニカ|3351円|
|子供部屋リフォーム|238440円|
|.||
|.||
|.||
というような商品リストがあり、この中で好きな組み合わせで買い物をして、合計が50万円に一番近い人の勝ち、というものです。
**データの用意
とりあえず、こんなリストを作ってデータを与えます。
let goods = [ ("プロ野球", 19373)
("ディズニーランド", 20453)
("回転ずし", 15906)
("ピアニカ", 3351)
("子供部屋リフォーム", 238440)
("デジタルビデオカメラ", 156097)
("お花畑", 29087)
("たこ焼き", 534)
("フーセンガム", 134)
("電動歯ブラシ", 4282)
("CDプレーヤー", 36307)
("マーブルチョコレート", 149)
("弁当箱", 950)
("さけ缶", 568)
("リポD", 1737)
("机いす", 67275)
("サーカス", 11419)
("五月人形", 208730)
("目覚まし時計", 2250)
("ロボット", 109385)
2012-05-20T14:12:41+09:00
1337490761
-
while展開編
https://w.atwiki.jp/fsharpmaster/pages/31.html
*StatefulFuncはなぜ動くか while展開編(オマケ)
**1.whileを使ったループの導入
StateBuilderにはWhileメソッドも実装されており、計算式の中にwhileループを記述できます。whileループはその構造上破壊的な代入が伴うのであまり関数型プログラミングで使われることがありませんが、せっかくなのでこれも試してみましょう。などと調子よく書き始めてから色々試したのですが、想像以上にイバラの道でした。ほとんど参考になる情報がなく、あっても間違っていたりで何日も悩まされました。
そんなこんなで書いたのがこのclaculatorActionsです。
let GetTotal = StatefulFunc (fun (total, history) -> total, (total, history))
let calculatorActions =
state {
do! Add 3
let! total = GetTotal
let stat = ref total
while (!stat > 0) do
do! Subtract 1
let! total = GetTotal
stat := total
return "End"
}
let res, stat = Run calculatorActions (0, [])
これを実行すると、以下のような実行結果が得られます。
val calculatorActions : StatefulFunc<(int * string list),string> =
StatefulFunc <fun:Delay@184>
val stat : int * string list = (0, ["1を減算"; "1を減算"; "1を減算"; "3を加算"])
val res : string = "End"
最初に3を加算し、1を引きながらループを回って0になったら抜ける、という処理になっております。たったこれだけなのに、意外にごちゃごちゃしてしまいました。let!でそのまま参照変数を
2012-05-20T01:52:40+09:00
1337446360
-
Win8・Winタブ・VS11
https://w.atwiki.jp/fsharpmaster/pages/30.html
*WindowsタブレットとF#とWindows8とVS11と私
**Acer Iconiatab W500とWindows8
#ref(IMAG0061s.jpg)
こんな感じです。
**付属PDFリーダーとSICP日本語版
#ref(IMAG0058s.jpg)
付属PDFリーダーは、これだけでWindows8入れる意味があるほど快適です。さらばAdobeReader。
Windowsタブのちょっと縦長の画面は、大部分の自炊技術書で余白を取るとぴったりトリミングが合います。SICPなど、このためにモニタの縦横比を決めたのかと思うほどです。
ちなみにSICPとは、「計算機プログラムの構造と解釈」という、その筋ではバイブル的な本です。
**VisualStudio11とF#3.0
#ref(IMAG0059s.jpg)
VSはレイアウト変更が自在なので、縦に使ってもまったく違和感がありません。
**ソフトウェアキーボード
#ref(IMAG0060s.jpg)
これで電車で立ったまま入力できます。
ただしなぜかAltキーがないので、F#でよく使うAlt+Enterが使えません。何か方法あるのかなぁ。
**その他の自炊書籍
全体的にやはり縦長の画面のほうがぴったりくる感じ。こう考えると自炊書籍を読むならiPadの縦横比よりもこっちのほうが多くの場合横が余らないと思う。ただ、マンガはちょっと天地が余るかな。
#ref(IMAG0062s.jpg)
↑ いわゆる「TaPL」。英文技術書代表。ぴったり。
#ref(IMAG0063s.jpg)
↑ 「λカ娘」。同人誌系代表。ぴったり。
#ref(IMAG0064s.jpg)
↑ 「プログラミングF#」。オライリー代表。やや天地が余ります。ちなみに「実践!~」はもう少し天地が余ります。
#ref(IMAG0065s.jpg)
↑ 「ものまね鳥をまねる」。小版代表。
#ref(IMAG0066s.jpg)
↑ 「マンガでわかる微分積分」。マンガ代表(苦笑)。マンガは結構天地が余ります。でもiPadだと左右が余るような気が。
(文責:片山 功士 2012/03/07)
今日:&coun
2012-03-08T09:09:00+09:00
1331165340