Template Haskell: GHC stage restriction and how to overcome -


i have following code in module:

{-# language templatehaskell #-}  module alpha  import language.haskell.th import data.list  data alpha = alpha { name :: string, value :: int } deriving (show) findname n = find ((== n) . name)  findx obj = sequence [vald pat bod []]             nam = name obj         pat = varp (mkname $ "find" ++ nam)         bod = normalb [| findname nam |] 

and have following in main file:

{-# language templatehaskell #-}  import alpha  1   = alpha "one" 1 2   = alpha "two" 2 3 = alpha "three" 3 xs    = [one, 2 , three]  findone = findname "one" findtwo = findname "two"  $(findx three) -- fails $(findx (alpha "four" 4)) -- works  main = putstrln "done" 

i'd $(findx three) create findthree = findname "three" me. instead, error:

ghc stage restriction: `three'   used in top-level splice or annotation,   , must imported, not defined locally in first argument of `findx', namely `three' in expression: findx 3 

how overcome this? rather not have define one, two, etc. in separate file.

second question why $(findx (alpha "four" 4)) work without problems?

i'm not across template haskell myself, based on limited understanding problem three in sense "still being defined" when ghc trying compile $(findx three), while component pieces of $(findx (alpha "four" 4)) defined.

the fundamental issue definitions in same module affect meaning of each other. due type inference mutual recursion. definition x = [] mean lots of different things, depending on context; binding x list of int, or list of io (), or else. ghc might have process whole module figure out does mean (or it's error).

the code template haskell emits module that's being compiled has considered analysis. means template haskell code has run before ghc has figured out definitions in module mean, , logically can't use of them.

things have been imported other modules otoh have been checked when ghc compiled that module. there no more information needs learned them compiling module. can accessed , used before compilation of code in module.

another way think it: maybe three isn't supposed of type alpha. maybe typo , constructor should have been alphz. ghc finds out sorts of errors compiling other code in module uses three see whether introduces inconsistency or not. if that code uses or used things emitted $(findx three)? don't know code that's going until run it, can't settle question of whether three typed until after run it.

it of course possible lift restriction bit in cases (i have no idea whether easy or practical). maybe make ghc consider "defined early" if imported or if uses other things "defined early" (and perhaps has explicit type signature). maybe try compiling module without running th code , if manages typecheck three before runs errors feed th code , recompile everything. downside (besides work involved) making more complicated state exact restrictions on can pass template haskell.


Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -