- Xamarin Studio をインストールすることで、F#のラインタイムもインストールされる
プラグインインストール
- MonoPath に /usr/local/bin を設定
$ fsharpi
- 1+1;;
val it : int = 2
-
- let list = [1..5]
- printfn "list: %A" list;;
list: [1; 2; 3; 4; 5]
$ touch hello.fs
$ vim hello.fs
#!/usr/bin/env fsharpi
printfn "Hello World"
//.netメソッドも使える
//System.Console.WriteLine "Hello World"
$ chmod 777 hello.fs
$ ./hello.fs
Hello world
#!/usr/bin/env fsharpi
// 変数束縛
// ・printfn は printf 的な振る舞いをするもの
let list = [1..5]
printfn "list: %A" list
// リスト要素を合計する関数
// ・変数束縛も関数定義も同じletで行う
// ・オフサイドルールが適用されるので、doneやendを省略可能、スコープもオフサイドラインで限定される
let rec sum' list =
match list with
| [] -> 0
| x::xs -> x + sum' xs
// リスト要素を合計する関数を Haskell で定義すると
// sum' [] = 0
// sum' (x:xs) = x + sum' xs
// 関数を適用する
list |> sum' |> printfn "sum: %A"
// パイプライン演算子を利用して、読みやすく
// これと同じ意味 printfn "%A" ( sum' list )
// haskellだと print $ sum' list
// -----------------------------------
// function式:引数が1つのパターンマッチ糖衣構文
let rec sum'' = function
| [] -> 0
| x::xs -> x + sum'' xs
// -----------------------------------
// リスト要素を逆順にする関数
// ・リスト最後に要素を追加する演算子はhaskell同様存在しないため、@演算子でリスト結合する
let rec reverse' = function
| [] -> []
| x::xs -> (reverse' xs) @ [x]
list |> reverse' |> printfn "rvrs: %A"
// haskellでは
// reverse' [] = []
// reverse' (x:xs) = reverse' xs ++ [x]
// -----------------------------------
// リスト先頭からn個を抽出する関数
// ・複数値引数を取るため、function式では記述できない
// ・また複数値に対してパターンマッチができない?ため、タプル化して引数を1つにしてマッチする
let rec take' n list =
match (n,list) with
| (n,_) when n < 1 -> []
| (_,[]) -> []
| (n,x::xs) -> x :: take' (n - 1) xs
list |> take' 2 |> printfn "take: %A"
// haskellでは
// take' _ [] = []
// take' n _ | n < 1 = []
// take' n (x:xs) = x : take' (n - 1) xs
// F#ではガードはwhenで記述する
// でもこんな書き方でもOK
let rec take'' n list =
match list with
| _ when n < 1 -> []
| [] -> []
| x::xs -> x :: take'' (n - 1) xs
// -----------------------------------
// FizzBuzz
// ・再帰処理がない場合には、キーワード rec が不要
let fizzbuzz = function
| n when n % 15 = 0 -> "FizzBuzz"
| n when n % 5 = 0 -> "Buzz"
| n when n % 3 = 0 -> "Fizz"
| n -> n |> string
// リストの各要素に適用したいので、map関数を利用する
list |> List.map fizzbuzz |> printfn "fizz: %A"
// haskellでは
// fizzbuzz n
// | n `mod` 15 == 0 = "FizzBuzz"
// | n `mod` 5 == 0 = "Buzz"
// | n `mod` 3 == 0 = "Fizz"
// | otherwise = show n
// -----------------------------------
// Fibonacci
let rec fib = function
| n when n < 0 -> 0
| n when n < 2 -> n
| n -> fib(n - 2) + fib(n - 1)
fib 6 |> printfn "fibo: %A"
// haskellでは
//fib 0 = 0
//fib 1 = 1
//fib n | n > 1 = fib (n - 2) + fib (n - 1)
// -----------------------------------
// Listモジュール
List.length list |> printfn "leng: %A"
List.isEmpty list |> printfn "empt: %A"
List.rev list |> printfn "rev: %A"
// funキーワードでラムダ式を記述
// let twice x = x * x と同じ
let twice = fun x -> x * x
List.map twice list |> printfn "twce: %A"
//畳み込み
List.reduce (+) list |> printfn "rdce: %A"
// 初期値を取るreduce
List.fold (+) 1 list |> printfn "fold: %A"