-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Higher library allows derivation of 'false' #17
Comments
Interesting. As you say, I don't think it really constitutes a bug. For a start, if you strip all the type annotations away and replace type empty = |
let inj x = `Box x
let prj = function `Box x -> x
let eqv_1 = fun r p -> r () p
let eqv_2 = fun np -> fun eq xp -> np xp
let bad_1 = fun b -> eqv_1 b (inj b)
let bad_2 = fun nb -> eqv_2 (fun b -> nb (prj b))
let absurd : empty =
let b = bad_2 bad_1 in
bad_1 b;; which also type checks fine, so it doesn't seem like I'm curious if the same thing happens in Haskell, since I tend to think of Higher as providing Haskell-style type constructors in OCaml, and they don't have any eqi-recursive types so maybe the simpler version doesn't already work there. |
Thanks for the interesting example, @stedolan.
Oleg describes a somewhat similar example in Impredicativity + injectivity + type case analysis = inconsistency (Russell paradox). Here's a port to OCaml with type empty = |
type ('a,'b) iapp = App of ('a, 'b) app
type 'c r = MkR : (((unit, 'c) iapp, 'c) iapp -> empty) -> (unit, 'c) iapp r
module R = Newtype1(struct type 'a t = 'a r end)
let cond_false : (unit, R.t) iapp r -> empty =
fun (MkR f as x) -> f (App (R.inj x))
let absurd : empty =
cond_false (MkR (fun (App x) -> cond_false (R.prj x)))
Indeed, with polymorphic variants, type inference can be made to introduce recursive types, and it's straightforward to write non-terminating programs without explicitly introducing recursion. Here's one such (complete) example: (fun (`x x) -> x (`x x)) (`x (fun (`x x) -> x (`x x))) |
It's debatable whether this is a bug - there's no segfaulting, just nontermination. But the nontermination arises without any use of recursion or loops at the type or value level, using one call to
Newtype1
:This is an OCaml port of Alexandre Miquel's Coq program, showing that the mixture of injectivity, impredicativity and large type parameters is unsound. (The first two are present in OCaml, the third is added by
higher
).The text was updated successfully, but these errors were encountered: