あなたが調べている興味深いプロパティは、選択した任意の型undefined
の型を持つ、つまり制約がないということです。他の人が指摘しているように、エラーまたは無限ループと見なされる可能性があります。それは「空虚な真実の陳述」と考えたほうがよいと私は主張したい。これは、停止問題に密接に関連する型システムではほぼ避けられない穴ですが、ロジックの観点から考えると楽しいものです。a
a
undefined :: a
undefined
型を使ったプログラミングについて考える 1 つの方法は、それがパズルだということです。誰かがあなたに型を与え、その型の関数を実装するように求めます。例えば
Question: fn :: a -> a
Answer: fn = \x -> x
は簡単です。a
for any typeを生成する必要がありa
ますが、入力として 1 つが与えられているため、それを返すことができます。
でundefined
、このゲームはいつも簡単です
Question: fn :: Int -> m (f [a])
Answer: fn = \i -> undefined -- backdoor!
だから、それを取り除きましょう。undefined
あなたがそれのない世界に住んでいるときに、それを理解するのは最も簡単です。今、私たちのゲームは難しくなっています。可能な場合もある
Question: fn :: (forall r. (a -> r) -> r) -> a
Answer: fn = \f -> f id
しかし、突然、それが不可能になることもあります。
Question: fn :: a -> b
Answer: fn = ??? -- this is `unsafeCoerce`, btw.
-- if `undefined` isn't fair game,
-- then `unsafeCoerce` isn't either
またはそれは?
-- The fixed-point combinator, the genesis of any recursive program
Question: fix :: (a -> a) -> a
Answer: fix = \f -> let a = f a in a
-- Why does this work?
-- One should be thinking of Russell's
-- Paradox right about now. This plays
-- the same role as a non-wellfounded set.
let
Haskellの束縛は怠惰で(一般的に)再帰的であるため、これは合法です。今、私たちは黄金です。
Question: fn :: a -> b
Answer: fn = \a -> fix id -- This seems unfair?
組み込みがなくてundefined
も、古い無限ループを使用してゲーム内で再構築できます。タイプをチェックアウトします。本当にundefined
Haskell に取り込まれないようにするには、停止問題を解決する必要があります。
Question: undefined :: a
Answer: undefined = fix id
これまで見てきたundefined
ように、 は任意の値のプレースホルダーにできるため、デバッグに役立ちます。残念ながら、無限ループまたは即時のクラッシュにつながるため、操作にはひどいものです。また、チートを可能にするため、ゲームにとっても非常に悪いことです。最後に、言語に (潜在的に無限の) ループがある限り、そうでないことはかなり難しいことを実証できたことを願っています。undefined
真にundefined
. 彼らがこれを行うのは、私が発明したこのゲームが、場合によっては実際に非常に価値があるからです。論理のステートメントをエンコードできるため、非常に厳密な数学的証明を形成するために使用できます。型は定理を表し、プログラムはその定理が実証されていることを保証します。の存在はundefined
、すべての定理が実証可能であることを意味し、したがってシステム全体が信頼できないものになります。
しかし、Haskell では、プルーフよりもループに関心がfix
あるため、undefined
.