[GHC] #10404: GHC panic when creating a monomorphised pattern synonym for GADT

GHC ghc-devs at haskell.org
Mon May 11 17:26:40 UTC 2015


#10404: GHC panic when creating a monomorphised pattern synonym for GADT
-------------------------------------+-------------------------------------
        Reporter:  Iceland_jack      |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.10.1-rc1
      Resolution:                    |                Keywords:
Operating System:  Linux             |            Architecture:  x86
 Type of failure:  GHC rejects       |               Test Case:
  valid program                      |                Blocking:
      Blocked By:                    |  Differential Revisions:
 Related Tickets:                    |
-------------------------------------+-------------------------------------

Old description:

> I have an expression
>
> {{{#!hs
> {-# LANGUAGE GADTs           #-}
> {-# LANGUAGE PatternSynonyms #-}
>
> data Exp a where
>   Fun :: (a -> b) -> (Exp a -> Exp b)
> }}}
>
> and I want to create a pattern synonym for Int-expressions:
>
> {{{#!hs
> -- This works:
> --   pattern IntFun :: (a -> b) -> (Exp a -> Exp b)
> --   pattern IntFun f x = Fun f x
>
> pattern IntFun :: (Int -> Int) -> (Exp Int -> Exp Int)
> pattern IntFun f x = Fun f x
> }}}
>
> which results in
>
> {{{#!hs
> % ghci -ignore-dot-ghci Panic.hs
> GHCi, version 7.10.0.20150316: http://www.haskell.org/ghc/  :? for help
> [1 of 1] Compiling Main             ( Panic.hs, interpreted )
>
> Panic.hs:8:28:
>     Couldn't match type ‘a’ with ‘Int’
>       ‘a’ is a rigid type variable bound by
>           a pattern with constructor
>             Fun :: forall b a. (a -> b) -> Exp a -> Exp b,
>           in a pattern synonym declaration
>           at Panic.hs:8:22
>     Expected type: Int -> Int
>       Actual type: a -> Int
>     Relevant bindings include
>       b :: Exp a (bound at Panic.hs:8:28)
>       a :: a -> Int (bound at Panic.hs:8:26)
> Failed, modules loaded: none.
> }}}
>
> So I try to be sneaky:
>
> {{{#!hs
> pattern IntFun :: (a ~ Int) => (a -> b) -> (Exp a -> Exp b)
> pattern IntFun f x = Fun f x
>
> -- % ghci -ignore-dot-ghci Panic.hs
> -- …
> --     Couldn't match type ‘a’ with ‘Int’
> --       ‘a’ is a rigid type variable bound by
> --           the type signature for IntFun :: (a1 -> b) -> Exp a1 -> Exp
> b
> --           at Panic.hs:8:22
> }}}
>
> and if I constrain both type variables it panics
>
> {{{#!hs
> pattern IntFun :: (a ~ Int, b ~ Int) => (a -> b) -> (Exp a -> Exp b)
> pattern IntFun f x = Fun f x
>
> --     Couldn't match type ‘b’ with ‘Int’
> --       ‘b’ is untouchable
> --         inside the constraints ()
> --         bound by the type signature for
> --                    IntFun :: (a1 -> b) -> Exp a1 -> Exp b
> --         at Panic.hs:8:9-14ghc: panic! (the 'impossible' happened)
> --   (GHC version 7.10.0.20150316 for i386-unknown-linux):
> --         No skolem info: b_alF[sk]
> --
> -- Please report this as a GHC bug:
> http://www.haskell.org/ghc/reportabug
> }}}
>
> The final version should look like:
>
> {{{#!hs
> type Name = String
> data Exp a where
>   Fun :: Name -> (a -> b) -> (Exp a -> Exp b)
>   ...
>
> pattern Suc :: Exp Int -> Exp Int
> pattern Suc n <- Fun _     _     n where
>         Suc n =  Fun "suc" (+ 1) n
> }}}
>
> Shouldn't this work?

New description:

 I have an expression

 {{{#!hs
 {-# LANGUAGE GADTs           #-}
 {-# LANGUAGE PatternSynonyms #-}

 data Exp a where
   Fun :: (a -> b) -> (Exp a -> Exp b)
 }}}

 and I want to create a pattern synonym for Int-expressions:

 {{{#!hs
 -- This works:
 --   pattern :: (a -> b) -> (Exp a -> Exp b)
 --   pattern IntFun f x = Fun f x

 pattern :: (Int -> Int) -> (Exp Int -> Exp Int)
 pattern IntFun f x = Fun f x
 }}}

 which results in

 {{{#!hs
 % ghci -ignore-dot-ghci Panic.hs
 GHCi, version 7.10.0.20150316: http://www.haskell.org/ghc/  :? for help
 [1 of 1] Compiling Main             ( Panic.hs, interpreted )

 Panic.hs:8:28:
     Couldn't match type ‘a’ with ‘Int’
       ‘a’ is a rigid type variable bound by
           a pattern with constructor
             Fun :: forall b a. (a -> b) -> Exp a -> Exp b,
           in a pattern synonym declaration
           at Panic.hs:8:22
     Expected type: Int -> Int
       Actual type: a -> Int
     Relevant bindings include
       b :: Exp a (bound at Panic.hs:8:28)
       a :: a -> Int (bound at Panic.hs:8:26)
 Failed, modules loaded: none.
 }}}

 So I try to be sneaky:

 {{{#!hs
 pattern :: (a ~ Int) => (a -> b) -> (Exp a -> Exp b)
 pattern IntFun f x = Fun f x

 -- % ghci -ignore-dot-ghci Panic.hs
 -- …
 --     Couldn't match type ‘a’ with ‘Int’
 --       ‘a’ is a rigid type variable bound by
 --           the type signature for IntFun :: (a1 -> b) -> Exp a1 -> Exp b
 --           at Panic.hs:8:22
 }}}

 and if I constrain both type variables it panics

 {{{#!hs
 pattern :: (a ~ Int, b ~ Int) => (a -> b) -> (Exp a -> Exp b)
 pattern IntFun f x = Fun f x

 --     Couldn't match type ‘b’ with ‘Int’
 --       ‘b’ is untouchable
 --         inside the constraints ()
 --         bound by the type signature for
 --                    IntFun :: (a1 -> b) -> Exp a1 -> Exp b
 --         at Panic.hs:8:9-14ghc: panic! (the 'impossible' happened)
 --   (GHC version 7.10.0.20150316 for i386-unknown-linux):
 --         No skolem info: b_alF[sk]
 --
 -- Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug
 }}}

 The final version should look like:

 {{{#!hs
 type Name = String
 data Exp a where
   Fun :: Name -> (a -> b) -> (Exp a -> Exp b)
   ...

 pattern Suc :: Exp Int -> Exp Int
 pattern Suc n <- Fun _     _     n where
         Suc n =  Fun "suc" (+ 1) n
 }}}

 Shouldn't this work?

--

Comment (by Iceland_jack):

 A quick but unsatisfying solution was adding a tag:

 {{{#!hs
 data Tag ty where
   ITag :: Tag Int
   …

 data Exp a where
   Fun₁ :: Name -> Tag a          -> (a -> b)      -> (Exp a -> Exp b)
   Fun₂ :: Name -> Tag a -> Tag b -> (a -> b -> c) -> (Exp a -> Exp b ->
 Exp c)
   …

 pattern Suc :: Exp Int -> Exp Int
 pattern Suc n <- Fun₁ "suc" _succ n where
         Suc n =  Fun₁ "suc"  succ n
 }}}

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


More information about the ghc-tickets mailing list