matarillo.com

The best days are ahead of us.

9.5 F# 1.0 -- 機能コアの改善:アクティブパターン

2021-09-25 00:00:21

1980年代から、強く型付けされた関数型プログラミング言語の最も人気のある機能の1つはパターンマッチングであり続けました。 F# とOCamlでは match ... with ... 構成体で表されています。 Wadlerによるビューの研究[Wadler 1987]以来、パターンマッチングには抽象化に欠ける問題があることが認識されていました: 既存のデータ型または抽象データ型に対して新しいパターンマッチング構成体を書くことはできません。 2005年のF# の「実証」の間に、SPiMやStatic Driver Verifierのような実世界のOCamlコードベースにおけるこの問題の重要性が、私には明らかになりました: これらのコードベースでは、型の実装の詳細がパターンマッチングによってコードに「漏れて」いるため、コア表現の変更が困難になっているケースが多数ありました。 2006年初めに、私はこれについてF# では何をすべきかを決定するプロセスを開始しました。 この時に私が受けた大きな影響の一つは、定理証明器DECLAREの証明言語に「証明分解」の構成体を設計し、使用した経験でした[Syme 1999b]。 この分解構成体は、パターンマッチングと同様の役割を果たしますが、後続の証明責務で任意の分解ステップを実行することができるものでした。 このことから、プログラミング言語には拡張可能な分解構成体が根本的に欠けており、そのような構造はシンプルで使いやすいものでなければならないと確信しました。

「アクティブパターン」や「ビュー」という考え方は学術界では取り上げられていましたが、 強く型付けされた関数型プログラミングの実用システムでは実装されたことはありませんでした[Erwig 1996]。 F# は、内部表現が非公開である.NETオブジェクト型と相互運用する必要があったため、拡張可能なパターンマッチングを追加するのは当然のことでした。 2006年5月、Gregory Neverovがプロジェクトにインターンとして参加し、このトピックの担当に割り当てられました。 プロトタイプがすぐに登場し、7月16~21日にボストンのWG 2.8で発表されました[Hinze 2019]。 Simon Peyton Jonesは当時F# について非常に役立つアドバイスをしました。 Haskellにビューパターンを追加しようとするさまざまな試みについて私に説明してくれたのです。 その中で、そのような機能を追加するにあたり、「努力に見合うだけの価値があるので」やらなければいけないこと、すなわち宣言と使用の簡単さについて強調していました。 F# アクティブパターンの初期実装は2006年8月にリリースされ、その後にICFPの論文が続き[Syme et al. 2007]、 それからずっと、この機能はF# 言語の中で非常に広く使われている部分であり続けています[Syme 2006i]。

F# のアクティブパターンでは、部分、完全、およびマルチケースのパターンを使用できます。 パーシャルアクティブパターンを定義して、文字列を整数または真偽値にパースする例を次に示します。

// アクティブパターンの作成
let (|Int|_|) str =
    match System.Int32.TryParse(str) with
    | (true, i) -> Some i
    | _ -> None

// アクティブパターンの作成
let (|Bool|_|) str =
    match System.Boolean.TryParse(str) with
    | (true, b) -> Some b
    | _ -> None

このようにパターンを構成した後は、通常の match .. with 式の一部として使用できます。

// パターンを呼び出す関数の作成
let testParse str =
    match str with
    | Int i -> printfn "The value is an int '%i'" i
    | Bool b -> printfn "The value is a bool '%b'" b
    | _ -> printfn "The value '%s' is something else" str

// テスト
testParse "12"
testParse "true"
testParse "abc"

この設計はすぐにF# 以外にも影響を及ぼしました。 先ほど述べたWG 2.8ワークショップの参加者の一人にMartin Oderskyがいて、2006年7月25日に彼から返信をもらいました。

WG 2.8であなたと議論したのはとても楽しかったです。 その後、私はScalaでアクティブパターンをどう扱うか考えてきました。 実在型を依存型で置き換えることができるようです。 今のところ、GADTのような振る舞いをさせる方法はまだ明確ではありませんが。

このEメールと最初のEPFL論文[Emir et al. 2007]から見ると、F# にアクティブパターンを追加したことはScalaの設計に何らかの影響を与えたようです。 F# (アクティブパターン)とScala(抽出子)のそれぞれのメカニズムの最終版は、ほぼ同時に設計され実装されました。


インデックスへ戻る