TH, tuples and "impossible happened" problem

Simon Peyton-Jones simonpj at microsoft.com
Fri Apr 14 07:31:07 EDT 2006


I'm sorry I've been slow in replying to this.

Short summary: your program has a bug, but GHC still should not crash.

The bug is that you extracted the Name of the *type constructor* (,,) from the type of 'x, but you then used it as a *data constructor* in the pattern.

Solution: when you have the Name of the type constructor, use 'reify' again to get the data constructors.


Meanwhile I will make GHC complain more gracefully.

Simon

| -----Original Message-----
| From: glasgow-haskell-bugs-bounces at haskell.org [mailto:glasgow-haskell-bugs-
| bounces at haskell.org] On Behalf Of Václav Haisman
| Sent: 19 March 2006 16:06
| To: glasgow-haskell-bugs at haskell.org
| Subject: TH, tuples and "impossible happened" problem
| 
| Hi,
| I have a little problem with Template Haskell. I have been trying make a
| template function that would allow me to read any element of tuple
| without explicit knowledge of how wide the tuple is. I have done some
| code but recently I have been stopped by GHC's "impossible happened":
| 
| 
| Compiler output:
| 
| Chasing modules from: MyTHUse.hs
| Compiling MyTH             ( ./MyTH.hs, ./MyTH.o )
| Compiling Main             ( MyTHUse.hs, MyTHUse.o )
| Loading package base-1.0 ... linking ... done.
| Loading package haskell98-1.0 ... linking ... done.
| Loading package template-haskell-1.0 ... linking ... done.
| ghc: panic! (the `impossible' happened, GHC version 6.4.1):
|         tyThingDataCon Type constructor `DataziTuple.Z3T{(w) tc 49}'
| 
| Please report it as a compiler bug to glasgow-haskell-bugs at haskell.org,
| or http://sourceforge.net/projects/ghc/.
| 
| --------------------------------------------------------------------------
| MyTH.hs:
| 
| module MyTH where
| 
| import Language.Haskell.TH
| import Language.Haskell.TH.Syntax
| import Language.Haskell.TH.Ppr
| 
| -- TI data_constructor param_count
| data TupleInfo = TI Name Int
| 
| --
| getTupleInfo :: Name -> Q TupleInfo
| getTupleInfo var_name =
|     do
|     info <- reify var_name
|     case info
|          of
|          vi@(VarI _ typ _ _) ->
|              case typ
|                   of
|                   appt@(AppT _ _) -> return $ traverseAppT 0 appt
|                   _ -> error "Not a tuple-like type."
|          _ -> error "Not a variable."
|     where
|     traverseAppT n (AppT t1 _) = traverseAppT (n+1) t1
|     traverseAppT n (ConT name) = TI name (n+1)
| 
| --
| tupleGet :: Name -> Int -> Q Exp
| tupleGet var_name tuple_index =
|     do
|     (TI constr_name width) <- getTupleInfo var_name
|     param_name <- newName "tuple_elem_"
|     sub_patterns <- genPattern 1 width tuple_index param_name
|     lambda <-
|         lamE [conP constr_name (map return sub_patterns)]
|                  (varE param_name)
|     return lambda
|     where
|     genPattern counter n param_index param_name
|                | counter == (n+1) = return []
|                | counter == param_index =
|                    do
|                    p <- varP param_name
|                    rest <- genPattern (counter+1) n param_index param_name
|                    return (p:rest)
|                | otherwise =
|                    do
|                    wp <- wildP
|                    rest <- genPattern (counter+1) n param_index param_name
|                    return (wp:rest)
| 
| ------------------------------------------------------------------
| MyTHUse.hs:
| 
| import MyTH
| import System.IO
| import Language.Haskell.TH
| import Language.Haskell.TH.Syntax
| import Data.Tuple
| 
| x = (1,2,3)
| 
| get1Of3 = $(tupleGet 'x 1)
| 
| 
| --
| Vaclav Haisman
| 




More information about the Glasgow-haskell-bugs mailing list