nameofの罠

F# Advent Calendar 2020の11日目のエントリーです。

5日目に続いてまた nameof の話です。

nameof にはF#のプログラムとしては当然だけど忘れがちな制約があります。

何の問題もないように見えますが、これはコンパイルエラーです。

let f () = nameof f

これがダメなのは、 ff の定義本体ではまだ見えないのに参照しようとしているからです。

let f x =
  match x with
  | 0 -> 0
  | x -> f (x - 1) + x

これがダメなのと同じ理由ですね。

なので、もしこういうことがしたければ、

let rec f () = nameof f

のように rec を付ける必要があります。 再帰していないのに rec を付けるのは気持ち悪い気もしますが、これは仕方ないでしょう。

ちなみに、メソッドは定義本体で自分自身が見えるので、次のコードはコンパイルが通ります。

type t () =
  static member F() = nameof t.F