タイプ 'a->' bのML関数


19

私たちの教授は、型を持つOCamlの関数を考えるように頼みました。

'a -> 'b

つまり、何でもかまいませんが、異なるものを返すことができる1つの引数の関数です。

raise引数を無視する関数で使用することを考えました:

let f x = raise Exit

しかし、教授は、標準ライブラリの機能を必要としないソリューションがあると述べました。私は混乱'bしています。最初に持っていない場合、どうやって作ることができますか?

何が起こっているのかを理解したいので、スタックオーバーフローではなくここで質問しています。説明のないプログラムを見たくありません。


2
あなたの答えが後で彼を刺激するかもしれないタイプ理論家ではなく、あなたの答えでプログラミングを学んでいるCS101学生をターゲットにしてください。
ジル 'SO-悪であるのをやめる

それがどのように機能するかを理解した方法を説明すると役立ちますraise。そのため、教授が探しているソリューション(同じ理由でraise機能する)が機能する理由を説明する最善の方法を知っています。
sepp2k

@ sepp2k raise : exn -> 'aので、戻り値を取得できます。引数を無視します。
ジル「SO-悪であるのをやめる」


回答:


18

スケルトンはlet f x = BODYです。BODYであなただけの一般的な方法(例えば、整数を期待することを関数にそれを送信しない)でXを使用しなければならない、とあなたは、の値を返す必要があります任意の他のタイプを。しかし、後者の部分はどうすれば本当ですか?「すべての型'bについて、返される値は型の値です」というステートメントを満たす唯一の方法'bは、関数が返らないことを確認することです。正確には2つの可能性があります。BODYフォールトか、終了しないかのいずれかです。機能raise障害が発生し、次は終了しません。

let rec f x = f x

19

まず、いくつかの発言。型付けされたラムダ計算のみを使用する'a -> 'bと、型付けシステムが(カリーハワード同型を介して)直観主義の論理に対応しており、対応する式A → Bはトートロジーではないため、取得することはできません。

タプルやマッチング/条件などのその他の拡張機能*は、論理接続詞andに対応する製品タイプ、およびorに|対応する和タイプを追加して、いくつかの論理整合性を保持します。繰り返しますが、トートロジーではない式を証明できるので、そのタイプを生成することを期待しないでください。'a -> 'b

したがって、あなたの唯一の可能性は、次のようなロジックから逃れる他の構造を使用するraiseことです(ただし、この場合は許可されません)...またはlet rec!再帰により、終了することのないプログラムを作成できます。また、結果は生成されないため、任意の戻り値の型を指定できます。ここで、最も単純な非終了関数(結果を返すためにそれ自体を直接呼び出す関数)について考える場合:

let rec f x = f x

その型が正確であることに気付くでしょう'a -> 'b:提供された引数が何であれ、結果(決して計算されない)は任意の型を持つと仮定できます。

もちろん、これfは興味深い機能ではありませんが、それがポイントです。OCamlでは、型が有効な式のように見えない関数は疑わしい関数です。


質問者は最初の2つの段落の単語を理解していませんでしたが、私はあなたの文が好きです。
ジル 'SO-悪であるのをやめる

1

コンパイラプリミティブを使用すると、次のように記述できます。

external magic: 'a -> 'b = "%identity"

(実際、コンパイラのディストリビューションはこれを提供しますが、言語の一部ではありません)。これは安全ではないIDキャストです。

あなたの教授はほぼ間違いなくこれを望んでいません。ただし、これは私が知っている型を持つ唯一の便利な関数でもあり、'a -> 'b実際にOCamlディストリビューション自体で使用されています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.