[GHC] #14038: TypeApplications regression in GHC HEAD: ‘p0’ is untouchable inside the constraints: ()

GHC ghc-devs at haskell.org
Thu Jul 27 13:29:54 UTC 2017


#14038: TypeApplications regression in GHC HEAD: ‘p0’ is untouchable inside the
constraints: ()
-------------------------------------+-------------------------------------
           Reporter:  RyanGlScott    |             Owner:  (none)
               Type:  bug            |            Status:  new
           Priority:  high           |         Milestone:  8.4.1
          Component:  Compiler       |           Version:  8.3
  (Type checker)                     |
           Keywords:                 |  Operating System:  Unknown/Multiple
  TypeApplications                   |
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 This file:

 {{{#!hs
 {-# LANGUAGE AllowAmbiguousTypes #-}
 {-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE ExistentialQuantification #-}
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE TypeInType #-}
 {-# LANGUAGE TypeOperators #-}
 module Eliminator where

 import Data.Kind (Type)

 data family Sing (a :: k)
 data instance Sing (z :: [a]) where
   SNil  :: Sing '[]
   SCons :: Sing x -> Sing xs -> Sing (x:xs)

 data TyFun :: Type -> Type -> Type
 type a ~> b = TyFun a b -> Type
 infixr 0 ~>

 type family Apply (f :: k1 ~> k2) (x :: k1) :: k2
 type a @@ b = Apply a b
 infixl 9 @@

 data FunArrow = (:->) -- ^ '(->)'
               | (:~>) -- ^ '(~>)'

 class FunType (arr :: FunArrow) where
   type Fun (k1 :: Type) arr (k2 :: Type) :: Type

 class FunType arr => AppType (arr :: FunArrow) where
   type App k1 arr k2 (f :: Fun k1 arr k2) (x :: k1) :: k2

 type FunApp arr = (FunType arr, AppType arr)

 instance FunType (:->) where
   type Fun k1 (:->) k2 = k1 -> k2

 instance AppType (:->) where
   type App k1 (:->) k2 (f :: k1 -> k2) x = f x

 instance FunType (:~>) where
   type Fun k1 (:~>) k2 = k1 ~> k2

 instance AppType (:~>) where
   type App k1 (:~>) k2 (f :: k1 ~> k2) x = f @@ x

 infixr 0 -?>
 type (-?>) (k1 :: Type) (k2 :: Type) (arr :: FunArrow) = Fun k1 arr k2

 elimList :: forall (a :: Type) (p :: [a] -> Type) (l :: [a]).
             Sing l
          -> p '[]
          -> (forall (x :: a) (xs :: [a]). Sing x -> Sing xs -> p xs -> p
 (x:xs))
          -> p l
 elimList = elimListPoly @(:->)

 elimListTyFun :: forall (a :: Type) (p :: [a] ~> Type) (l :: [a]).
                  Sing l
               -> p @@ '[]
               -> (forall (x :: a) (xs :: [a]). Sing x -> Sing xs -> p @@
 xs -> p @@ (x:xs))
               -> p @@ l
 elimListTyFun = elimListPoly @(:~>) @_ @p

 elimListPoly :: forall (arr :: FunArrow) (a :: Type) (p :: ([a] -?> Type)
 arr) (l :: [a]).
                 FunApp arr
              => Sing l
              -> App [a] arr Type p '[]
              -> (forall (x :: a) (xs :: [a]). Sing x -> Sing xs -> App [a]
 arr Type p xs -> App [a] arr Type p (x:xs))
              -> App [a] arr Type p l
 elimListPoly SNil                      pNil _     = pNil
 elimListPoly (SCons x (xs :: Sing xs)) pNil pCons = pCons x xs
 (elimListPoly @arr @a @p @xs xs pNil pCons)
 }}}

 Typechecks in GHC 8.2.1 without issue, but fails in GHC HEAD:

 {{{
 $ ghc5/inplace/bin/ghc-stage2 --interactive Bug.hs
 GHCi, version 8.3.20170725: http://www.haskell.org/ghc/  :? for help
 Loaded GHCi configuration from /home/rgscott/.ghci
 [1 of 1] Compiling Eliminator       ( Bug.hs, interpreted )

 Bug.hs:59:12: error:
     • Couldn't match type ‘p0’ with ‘p’
         because type variables ‘a1’, ‘p’ would escape their scope
       These (rigid, skolem) type variables are bound by
         the type signature for:
           elimList :: forall a1 (p :: [a1] -> *) (l :: [a1]).
                       Sing l
                       -> p '[]
                       -> (forall (x :: a1) (xs :: [a1]).
                           Sing x -> Sing xs -> p xs -> p (x : xs))
                       -> p l
         at Bug.hs:(54,1)-(58,15)
       Expected type: Sing l
                      -> p '[]
                      -> (forall (x :: a1) (xs :: [a1]).
                          Sing x -> Sing xs -> p xs -> p (x : xs))
                      -> p l
         Actual type: Sing l
                      -> App [a1] (':->) * p0 '[]
                      -> (forall (x :: a1) (xs :: [a1]).
                          Sing x
                          -> Sing xs
                          -> App [a1] (':->) * p0 xs
                          -> App [a1] (':->) * p0 (x : xs))
                      -> App [a1] (':->) * p0 l
     • In the expression: elimListPoly @(:->)
       In an equation for ‘elimList’: elimList = elimListPoly @(:->)
     • Relevant bindings include
         elimList :: Sing l
                     -> p '[]
                     -> (forall (x :: a1) (xs :: [a1]).
                         Sing x -> Sing xs -> p xs -> p (x : xs))
                     -> p l
           (bound at Bug.hs:59:1)
    |
 59 | elimList = elimListPoly @(:->)
    |            ^^^^^^^^^^^^^^^^^^^

 Bug.hs:59:12: error:
     • Couldn't match type ‘p0’ with ‘p’
         ‘p0’ is untouchable
           inside the constraints: ()
           bound by a type expected by the context:
                      forall (x :: a1) (xs :: [a1]).
                      Sing x
                      -> Sing xs
                      -> App [a1] (':->) * p0 xs
                      -> App [a1] (':->) * p0 (x : xs)
           at Bug.hs:59:12-30
       ‘p’ is a rigid type variable bound by
         the type signature for:
           elimList :: forall a1 (p :: [a1] -> *) (l :: [a1]).
                       Sing l
                       -> p '[]
                       -> (forall (x :: a1) (xs :: [a1]).
                           Sing x -> Sing xs -> p xs -> p (x : xs))
                       -> p l
         at Bug.hs:(54,1)-(58,15)
       Expected type: Sing x
                      -> Sing xs
                      -> App [a1] (':->) * p0 xs
                      -> App [a1] (':->) * p0 (x : xs)
         Actual type: Sing x -> Sing xs -> p xs -> p (x : xs)
     • In the expression: elimListPoly @(:->)
       In an equation for ‘elimList’: elimList = elimListPoly @(:->)
     • Relevant bindings include
         elimList :: Sing l
                     -> p '[]
                     -> (forall (x :: a1) (xs :: [a1]).
                         Sing x -> Sing xs -> p xs -> p (x : xs))
                     -> p l
           (bound at Bug.hs:59:1)
    |
 59 | elimList = elimListPoly @(:->)
    |            ^^^^^^^^^^^^^^^^^^^
 }}}

 A workaround is to explicitly apply `p` with `TypeApplications` in line
 59:

 {{{#!hs
 elimList = elimListPoly @(:->) @_ @p
 }}}

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


More information about the ghc-tickets mailing list