[GHC] #9636: Function with type error accepted

GHC ghc-devs at haskell.org
Mon Sep 14 23:41:01 UTC 2015


#9636: Function with type error accepted
-------------------------------------+-------------------------------------
        Reporter:  augustss          |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.8.3
      Resolution:                    |                Keywords:
Operating System:  Unknown/Multiple  |            Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |               Test Case:
      Blocked By:                    |                Blocking:
 Related Tickets:                    |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by DerekElkins):

 This is a fun one.  We can look at what some other systems do in similar
 situations.

 comment:17 talks about handling unevaluated terms and the discussion has
 been talking about partial functions.  One system that deals in this realm
 is Computational Type Theory (CTT), the type theory underlying NuPRL (and
 now JonPRL).  In NuPRL you can literally write the equivalent of:

 {{{#!hs
 T Int = Bool
 T   x = fix id
 }}}

 Obviously NuPRL doesn't loop forever when it encounters T Bool.  It will
 do some computation to see if it can decide the proposition, but if it
 can't it gives up and makes it a proof obligation that the user must
 discharge.  Since CTT is based on partial equivalence relations, T Bool ~
 T Bool presents no problem.  Reflexivity is not given, so that's a
 statement that needs to be proven.  Indeed, typing Lennart's f from the
 bug report, requires, as usual, deriving that T Bool :: * and in CTT this
 is by definition T Bool ~ T Bool.  Clearly GHC has evidence allowing it to
 automatically show the proof obligation is not achievable in this case.
 Thus the analogous situation in CTT would be a type error.

 In comment:19 Lennart mentions that we still have logic programming at the
 type level.  One way of interpreting this is to give (closed) type
 families Curry's semantics, i.e. narrowing, but restricted to functional
 relations, so no (truly) overlapping patterns.  This would be a language
 where a function returns at most one result rather than exactly one result
 as in a functional language.  Still, T Bool would narrow the result set to
 the empty set and thus be a type error.

 Alternatively, Lennart may have just been referring to working with
 uninterpreted functions, something commonly done in logic programming, but
 in no way restricted to logic programming.  Of course, T isn't an
 uninterpreted function, T Int ~ Bool.  We could say it's a quotient of a
 type of uninterpreted functions modulo the relation T Int ~ Bool.  We can
 push this idea a little.  If someone wants to play with the current
 behavior in a more explicit manner all one needs to do is open up Agda and
 type:
 {{{#!hs
 import Level

 data Unit : Set where U : Unit
 data Bool : Set where True : Bool; False : Bool

 data _==_ {l}{A : Set l} (a : A) : A -> Set l where
     refl :  a == a

 subst : {l : Level.Level}{A B : Set l} -> (A == B) -> A -> B
 subst refl x = x

 postulate T : Set -> Set
 postulate T_Bool_is_Unit : T Bool == Unit

 f : T Unit -> Bool
 f _ = True

 g : T Bool -> Unit
 g x = subst T_Bool_is_Unit x

 h : T Bool == T Bool -> Unit
 h refl = U
 }}}
 To handle overlapping, explicit inequality evidence needs to be provided.
 This suggests that like we can view a data declaration as adding a
 constructor to (codes for) *.  A type family could be viewed into making
 that data type a higher inductive type (from Homotopy Type Theory).

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9636#comment:26>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list