F#でのパターンマッチ。「match a with 〜」よりも 「a |> function 〜」を使おうぜ(異論は認める)
カンスウガタゲンガーは割と見逃しがちだけど、match a with ?と a |> function ?は完全互換ではありません #えふしゃーぷあるある #fsharp
2011-09-02 16:08:23 via web
@zecl え?そうなんですか?まったく同じものだと思ってました。。。
2011-09-02 18:08:31 via HootSuite to @zecl
以前、「F#では、パターンマッチを「match x with」と書く流派と「x |> function」と書く流派がございます。」という記事を書きました。
ほぼほぼ置き換えることが可能な、「match a with 〜」と 「a |> function 〜」ですが、
実は完全互換ではありません。これはカンスウガタゲンガーには割と気づきにくい違いかもしれません。
細かすぎて伝わらない程度の違いですが、カンスウガタゲンガーの@nakamura_toさんにリアクション頂いたのでちょっと書いてみます。
「match a with 〜」と 「a |> function 〜」の違い
結論から申し上げますと、functionによるパターンマッチは"クロージャー"であるということです。「a |> function 〜」をまじまじと見つめていただくとわかるように、とてもクロージャー感を醸し出しています。
「あ〜、言われてみればそうですね。」という感じではないでしょうか。
つまり、「functionによるパターンマッチではmutableな変数をキャプチャすることができない。」という違いがあります。
module Sample = let hoge = let hoge0 () = let mutable s = "ほげ" match s with | "ふが" -> () | x -> printfn "%s" s hoge1 () let hoge1 () = let mutable s = "ほげ" s |> function | "ふが" -> () | x -> printfn "%s" s // mutableな変数をキャプチャできないのでエラー hoge1 () let hoge0 () = let s = ref "ほげ" match !s with | "ふが" -> () | x -> printfn "%s" !s hoge0 () let hoge1 () = let s = ref "ほげ" !s |> function | "ふが" -> () | x -> printfn "%s" !s // Reference CellsはクロージャーでキャプチャできるのでOK hoge1 () () open System open Sample hoge Console.ReadLine () |> ignore
関数プログラミングなパラダイムを主体としているカンスウガタゲンガーは、
極力 mutable を用いないプログラミングをします。mutable を利用するとしても用途はとても限定的です。
また、パターンマッチさせた値を用いずに、直接 mutable な変数をキャプチャするような書き方も好ましくないので、通常そのような書き方はしないでしょう。
ですから、このわずかな違いを意識する機会はあまりないかもしれません。
完全互換ではありませんが、一般的なカンスウガタゲンガーが書く「match a with 〜」は、ほとんどの場合「a |> function 〜」に置き換え可能でしょう。
F#トリビア。いにしえからの言い伝えによると、パターンマッチを「match x with」と書く流派と「x |> function」と書く流派がございます。後者の方がネストを浅く保つことができるので私は好きです。 #fsharp
2011-05-12 16:35:17 via web
いっそのこと、パターンマッチは「a |> function 〜」で行うように統一してしまったほうが(コーディング規約的な意味で)、
パターンマッチ内で直接 mutable な変数をキャプチャするような書き方を抑止することができるので、
カンスウガタゲンガー的にはうれしいのかもしれません(異論は認める)。
好みというよりだだの自己満ですが、「a |> function 〜」の方がイケてると思うので私は多用しまくりんぐです。
F#の勉強会とかやりたい
北海道旭川市近郊でF#の勉強をしてる人 or してみたい人いるかなあ。もしいたら、何かコメントいただきたく。