Re: [Haskell-cafe] Non-termination of type-checking

2010-01-29 Thread Nicolas Pouillard
On Thu, 28 Jan 2010 18:32:02 -0800, Ryan Ingram ryani.s...@gmail.com wrote:
 But your example uses a recursive type; the interesting bit about this
 example is that there is no recursive types or function, and yet we
 can encode this loop.

The point is that you get the Fix type by (infintely) unfolding the
type definitions.

-- 
Nicolas Pouillard
http://nicolaspouillard.fr
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Non-termination of type-checking

2010-01-28 Thread Ryan Ingram
But your example uses a recursive type; the interesting bit about this
example is that there is no recursive types or function, and yet we
can encode this loop.

  -- ryan

On Wed, Jan 27, 2010 at 4:49 PM, Matthew Brecknell
matt...@brecknell.net wrote:
 Ryan Ingram wrote:
 The compiler doesn't loop for me with GHC6.10.4; I think GADTs still
 had some bugs in GHC6.8.

 That said, this is pretty scary.  Here's a simplified version that
 shows this paradox with just a single GADT and no other extensions.
 No use of fix or recursion anywhere!

 {-# LANGUAGE GADTs #-}
 module Contr where

 newtype I f = I (f ())
 data R o a where R :: (a (I a) - o) - R o (I a)

 run :: R o (I (R o)) - R o (I (R o)) - o
 run x (R f) = f x
 rir :: (R o) (I (R o))
 rir = R (\x - run x x)

 absurd :: a
 absurd = run rir rir

 I think that's essentially the same as this:

 data Fix a = Fix { unFix :: Fix a - a }

 run :: Fix a - Fix a - a
 run x f = unFix f x

 rir :: Fix a
 rir = Fix (\x - run x x)

 absurd :: a
 absurd = run rir rir

 Non-positive recursive occurrences in type definitions provide various
 ways to encode the Y-combinator in a typed lambda calculus, without the
 need for any recursive let primitive. Haskell allows such non-positive
 occurrences, but for strong normalisation, languages like Coq must
 disallow them.

 If you change data to newtype in the above, the GHC 6.10.4 compiler
 (but not GHCi) will loop. I think this is just a case of the infelicity
 documented here:

 http://www.haskell.org/ghc/docs/latest/html/users_guide/bugs.html

 Regards,
 Matthew



 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Non-termination of type-checking

2010-01-27 Thread Matthieu Sozeau

Dear Haskellers,

  while trying to encode a paradox recently found in Coq if one has
impredicativity and adds injectivity of type constructors [1] I
stumbled on an apparent loop in the type checker when using GADTs,
Rank2Types and EmptyDataDecls.

 {-# OPTIONS -XGADTs -XRank2Types -XEmptyDataDecls #-}

 module Impred where

The identity type

 data ID a = ID a

I is from (* - *) to *, we use a partial application of [ID] here.

 data I f where
  I1 :: I ID

The usual reification of type equality into a term.

 data Equ a b where
  Eqrefl :: Equ a a

The empty type

 data False

This uses impredicativity: Rdef embeds a (* - *) - *
object into R x :: *.

 data R x where
  Rdef :: (forall a. Equ x (I a) - a x - False) - R x

 r_eqv1 :: forall p. R (I p) - p (I p) - False
 r_eqv1 (Rdef f) pip = f Eqrefl pip

 r_eqv2 :: forall p. (p (I p) - False) - R (I p)
 r_eqv2 f = Rdef (\ eq ax -
case eq of -- Uses injectivity of type  
constructors

 Eqrefl - f ax)

 r_eqv_not_R_1 :: R (I R) - R (I R) - False
 r_eqv_not_R_1 = r_eqv1

 r_eqv_not_R_2 :: (R (I R) - False) - R (I R)
 r_eqv_not_R_2 = r_eqv2

 rir :: R (I R)
 rir = r_eqv_not_R_2 (\ rir - r_eqv_not_R_1 rir rir)

Type checking seems to loop here with ghc-6.8.3, which is a
bit strange given the simplicity of the typing problem.
Maybe it triggers a constraint with something above?

 -- Loops
 -- absurd :: False
 -- absurd = r_eqv_not_R_1 rir rir

[1] 
http://thread.gmane.org/gmane.science.mathematics.logic.coq.club/4322/focus=1405

-- Matthieu
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Non-termination of type-checking

2010-01-27 Thread Ryan Ingram
The compiler doesn't loop for me with GHC6.10.4; I think GADTs still
had some bugs in GHC6.8.

That said, this is pretty scary.  Here's a simplified version that
shows this paradox with just a single GADT and no other extensions.
No use of fix or recursion anywhere!

{-# LANGUAGE GADTs #-}
module Contr where

newtype I f = I (f ())
data R o a where R :: (a (I a) - o) - R o (I a)

run :: R o (I (R o)) - R o (I (R o)) - o
run x (R f) = f x
rir :: (R o) (I (R o))
rir = R (\x - run x x)

absurd :: a
absurd = run rir rir

  -- ryan

On Wed, Jan 27, 2010 at 8:27 AM, Matthieu Sozeau mat...@mattam.org wrote:
 Dear Haskellers,

  while trying to encode a paradox recently found in Coq if one has
 impredicativity and adds injectivity of type constructors [1] I
 stumbled on an apparent loop in the type checker when using GADTs,
 Rank2Types and EmptyDataDecls.

 {-# OPTIONS -XGADTs -XRank2Types -XEmptyDataDecls #-}

 module Impred where

 The identity type

 data ID a = ID a

 I is from (* - *) to *, we use a partial application of [ID] here.

 data I f where
  I1 :: I ID

 The usual reification of type equality into a term.

 data Equ a b where
  Eqrefl :: Equ a a

 The empty type

 data False

 This uses impredicativity: Rdef embeds a (* - *) - *
 object into R x :: *.

 data R x where
  Rdef :: (forall a. Equ x (I a) - a x - False) - R x

 r_eqv1 :: forall p. R (I p) - p (I p) - False
 r_eqv1 (Rdef f) pip = f Eqrefl pip

 r_eqv2 :: forall p. (p (I p) - False) - R (I p)
 r_eqv2 f = Rdef (\ eq ax -
                    case eq of -- Uses injectivity of type constructors
                     Eqrefl - f ax)

 r_eqv_not_R_1 :: R (I R) - R (I R) - False
 r_eqv_not_R_1 = r_eqv1

 r_eqv_not_R_2 :: (R (I R) - False) - R (I R)
 r_eqv_not_R_2 = r_eqv2

 rir :: R (I R)
 rir = r_eqv_not_R_2 (\ rir - r_eqv_not_R_1 rir rir)

 Type checking seems to loop here with ghc-6.8.3, which is a
 bit strange given the simplicity of the typing problem.
 Maybe it triggers a constraint with something above?

 -- Loops
 -- absurd :: False
 -- absurd = r_eqv_not_R_1 rir rir

 [1]
 http://thread.gmane.org/gmane.science.mathematics.logic.coq.club/4322/focus=1405

 -- Matthieu
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Non-termination of type-checking

2010-01-27 Thread Matthew Brecknell
Ryan Ingram wrote:
 The compiler doesn't loop for me with GHC6.10.4; I think GADTs still
 had some bugs in GHC6.8.
 
 That said, this is pretty scary.  Here's a simplified version that
 shows this paradox with just a single GADT and no other extensions.
 No use of fix or recursion anywhere!
 
 {-# LANGUAGE GADTs #-}
 module Contr where
 
 newtype I f = I (f ())
 data R o a where R :: (a (I a) - o) - R o (I a)
 
 run :: R o (I (R o)) - R o (I (R o)) - o
 run x (R f) = f x
 rir :: (R o) (I (R o))
 rir = R (\x - run x x)
 
 absurd :: a
 absurd = run rir rir

I think that's essentially the same as this:

data Fix a = Fix { unFix :: Fix a - a }

run :: Fix a - Fix a - a
run x f = unFix f x

rir :: Fix a
rir = Fix (\x - run x x)

absurd :: a
absurd = run rir rir

Non-positive recursive occurrences in type definitions provide various
ways to encode the Y-combinator in a typed lambda calculus, without the
need for any recursive let primitive. Haskell allows such non-positive
occurrences, but for strong normalisation, languages like Coq must
disallow them.

If you change data to newtype in the above, the GHC 6.10.4 compiler
(but not GHCi) will loop. I think this is just a case of the infelicity
documented here:

http://www.haskell.org/ghc/docs/latest/html/users_guide/bugs.html

Regards,
Matthew



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe