LoginSignup
0
1

More than 3 years have passed since last update.

引数の数と()の解釈

Last updated at Posted at 2020-02-24

ListやらSeqとかのパフォーマンス測定の時にコメント頂いた内容で
なぜ関数に()を付けないといけなかったか?がずっと不思議だった。

「F#の関数定義では()はつけなくていいハズなのに、なぜ明示的につけるのか?」という勘違いが、いらぬ混乱を招いていた。
C言語ファミリーの関数定義で必要なvoid main(){...}()とは意味合いが違う。

2020/2/26 誤りがある事をご指摘いただいたため、内容を訂正しました!

まとめ

わかりにくいのでunitを()、構文としての()をカッコと表現してます。

  • letは値を束縛するための機能である
  • F#では全ての関数が値とみなされる。関数値とも呼ぶ
  • ()はunit型の定数パターンである
  • 引数がないものは関数ではない
  • 引数があるものは関数である
  • 型注釈に使うカッコは関数定義の構文の一部ではない
  • 関数の定義とカッコには直接の関係はない(優先順位を持たせるために使う)
  • タプルを使うとカリー化は無効になる

letって何

名前と定義(値または関数)を関連付ける。

let t = 103    // 値を束縛
let s = "JNR"  // 値を束縛

let add1 x = x + 1 // 1つの引数を持つ関数を束縛
let add x y = x + y // 2つの引数を持つ関数を束縛

パターンって何

letやラムダ式や関数の引数(パラメータ)を処理するときに使われる。

let t = 103    // 定数パターン
let n = ()     // 定数パターン

let add1int (x:int) = x + 1 // 引数に型の注釈がつけられたパターン
let add1int (x:int) :int = x + 1 // 戻り値の型を明示

検証用コード

// unitの値(副作用あり)
let a = printfn "a" // unit

// unitの値(副作用なし)
let b = () // unit

// unit引数を受け取りunitを返す関数
let c () = printfn "b" // unit -> unit

// 引数xを受け取りunitを返す関数
let d x = printfn "%A" x // 'a -> unit

// dを冗長に書いた場合
let e = fun x -> printfn "%A" x // 'a -> unit

// 引数xに無駄にカッコをつけているだけ
let f (x) = printfn "(%A)" x // 'a -> unit

// gは引数xとyを受け取りunitを返す関数
let g x y = printfn "%A%A" x y // 'a -> 'b -> unit

// gを冗長に書いた場合
let h = fun x -> fun y -> printfn "%A%A" x y // 'a -> 'b -> unit

// 引数として、xとyのタプルを1つ受け取りunitを返す関数
let i (x, y) = printfn "(%A,%A)" x y // 'a * 'b -> unit

// intの値(副作用なし)
let j = 2 // int

// 2を返す関数
let k = fun _ -> 2 // 'a -> int
let l = fun () -> 2 // 'a -> int

0
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1